Skip to content

Missing taxable_roth_conversions in State Gross Income / AGI Definitions (AL, AR, NJ) #9352

Closed

Description

@jindal-git

When taxable_roth_conversions was added as a distinct variable from taxable_ira_distributions, it was added to the federal gross income sources (gov.irs.gross_income.sources), but was omitted from several state gross income / AGI definitions that explicitly list income components (AL, AR, NJ).

This causes state models to treat Roth conversions as non-taxable at the state level. In Alabama (which allows a deduction for federal income taxes paid), this omission creates a negative state marginal tax rate as Roth conversions rise, because federal tax increases while Alabama gross income remains unchanged.

Affected Files

  1. Alabama (AL):
    • policyengine_us/parameters/gov/states/al/tax/income/agi/gross_income_sources.yaml
  2. Arkansas (AR):
    • policyengine_us/parameters/gov/states/ar/tax/income/gross_income/sources/individual.yaml
    • policyengine_us/parameters/gov/states/ar/tax/income/gross_income/sources/joint.yaml
  3. New Jersey (NJ):
    • policyengine_us/parameters/gov/states/nj/tax/income/gross_income/non_negative_sources.yaml

Expected vs. Actual Behavior

  • Expected Behavior:

    • In AL, AR, and NJ, traditional IRA to Roth conversions are taxable income at the state level (just like taxable_ira_distributions) under Ala. Code § 40-18-14, Ark. Code § 26-51-404, and N.J.S. 54A:5-1 (Line 20a).
    • State AGI / gross income should increase when taxable_roth_conversions increases.
  • Actual Behavior:

    • Alabama (AL): al_agi stays flat at $100k when Roth conversions increase from $0 to $50k, while al_federal_income_tax_deduction increases. This reduces al_taxable_income and causes state income tax to decrease, resulting in a negative marginal tax rate (-0.75% to -1.35%).
    • Arkansas (AR) & New Jersey (NJ): State tax on Roth conversions is calculated as $0 regardless of conversion amount.

Reproduction Scenario (Alabama Negative Marginal Rate)

from policyengine_us import Simulation

sit_0 = {
    'people': {'you': {'age': {2026: 45}, 'long_term_capital_gains': {2026: 100000}, 'taxable_roth_conversions': {2026: 0}}},
    'tax_units': {'tax_unit': {'members': ['you']}},
    'households': {'household': {'members': ['you'], 'state_code': {2026: 'AL'}}}
}
sit_1 = {
    'people': {'you': {'age': {2026: 45}, 'long_term_capital_gains': {2026: 100000}, 'taxable_roth_conversions': {2026: 10000}}},
    'tax_units': {'tax_unit': {'members': ['you']}},
    'households': {'household': {'members': ['you'], 'state_code': {2026: 'AL'}}}
}

sim0 = Simulation(situation=sit_0)
sim1 = Simulation(situation=sit_1)

print("Roth = $0 AL Tax:", sim0.calculate('al_income_tax', 2026)[0])       # 4501.63
print("Roth = $10k AL Tax:", sim1.calculate('al_income_tax', 2026)[0])     # 4426.63 (-$75 tax on +$10k income!)

Proposed Solution

Add taxable_roth_conversions to the parameter YAML lists for:

gov.states.al.tax.income.agi.gross_income_sources
gov.states.ar.tax.income.gross_income.sources.individual
gov.states.ar.tax.income.gross_income.sources.joint
gov.states.nj.tax.income.gross_income.non_negative_sources

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions