AZ baseline non-refundable credit ordering applies charitable before dependent/family credits, contrary to Forms 140/301

Open Beginner friendly
#9,559 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
84/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
python
Domain
backend

Research direction

Start in policyengine_us/parameters/gov/states/az/tax/income/credits/non_refundable.yaml and inspect the 2019–2020 and 2021+ ordering blocks. Search for tests covering Arizona non-refundable credits, then compare the ordering with the cited Forms 140/301 instructions. Done means the applicable list matches the form sequence and relevant tests still pass.

Written by the indexing model from the issue text.

Description

Summary

The Arizona non-refundable credit ordering list applies the charitable contributions credit before the dependent and family tax credits, contrary to AZ Forms 140/301. In baseline the order is invisible (same total non-refundable credits, same az_income_tax), but it becomes dollar-relevant once the AZ refundable dependent credit contrib (PR #9531) is enabled.

The defect

policyengine_us/parameters/gov/states/az/tax/income/credits/non_refundable.yaml, from 2021 on, orders the credits as:

2021-01-01:
  - az_charitable_contributions_credit
  - az_dependent_tax_credit
  - az_family_tax_credit

Arizona's forms apply the dependent and family credits before any Form 301 credit (including the charitable contributions credits):

  • 2025 Form 140 booklet: line 49 Dependent Tax Credit, line 50 Family Income Tax Credit, line 51 nonrefundable credits from Form 301, line 52 "Subtract lines 49, 50, and 51 from line 48" (p. 26, p. 30).
  • 2025 Form 301 instructions, Part 2: line 31 tax subtotal; line 32 "the total amount of family income tax credit and dependent tax credit claimed on your income tax form" (Form 140 lines 50 and 49); line 33 = line 31 − line 32, floored at zero; "The total amount of tax credits you use cannot exceed the amount entered on line 33" (p. 3). The qualifying charitable organizations credit is line 39 of that section, drawing only on what remains (p. 4).
  • 2022 forms have the same sequence: 140i p. 21 and p. 24; 301i p. 3.

Ordering consequence

In baseline the order is invisible: whichever credit is labelled "applied," total non-refundable credits and az_income_tax are identical, so no existing test catches it. Once the AZ refundable dependent credit is on, the order changes a dollar outcome, because the refund strands the dependent credit and pays a refund the form would not.

Example (2026, single filer, one dependent under 17 with potential $125, az_income_tax_before_non_refundable_credits = $300, qualifying charitable organizations credit = $300, refundable.in_effect: true):

Form order Model order
Dependent credit applied $125 $0 (charitable takes the full $300 first)
Stranded dependent credit → refund $0 $125

The form gives the charitable credit a five-year carryforward and pays no refund; the model pays $125.

Proposed fix

Reorder the 2021+ list to dependent, family, then charitable. The 2019-2020 block ordering and any existing-test impact should be researched as part of the fix.

Context

This was surfaced by @hua7450 (Ziming) reviewing PR #9531 (Add AZ refundable dependent credit and MA/UT dependent exemption age-split contribs). Ziming validated that the refund mechanics are correct for the ordering the model uses (az_refundable_dependent_tax_credit keys off the same gov.states.az.tax.income.credits.non_refundable list and the same az_dependent_tax_credit ordering key as baseline, so potential − applied is exactly the stranded portion); the problem is the baseline list itself. He recommended filing the baseline reorder as a follow-up rather than expanding the scope of PR #9531. See his review comment for the full form citations and worked example.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LqCGPgxDukji8Bhs57c5rH

Dominant language
Python
Stars
163
Forks
213
Avg merge
2d 16h
Merged PRs (30d)
99

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from PolicyEngine/policyengine-us

All issues in PolicyEngine/policyengine-us

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.