Skip to content

Give the saver's credit its 50% rate at negative AGI - #10541

Merged
PavelMakarchuk merged 1 commit into
mainfrom
fix-10538-savers-credit-negative-agi
Oct 29, 2026
Merged

PavelMakarchuk merged 1 commit into
mainfrom
fix-10538-savers-credit-negative-agi

Conversation

@PavelMakarchuk

Copy link
Copy Markdown
Collaborator

Fixes #10538

Summary

gov.irs.credits.retirement_saving.rate.joint is a single-amount scale whose first threshold was $0. SingleAmountTaxScale.calc returns 0 for a base below the first threshold, so savers_credit_potential (Form 8880 line 10) was $0 when adjusted gross income was negative.

The Form 8880 (2025) line 9 table's first row has no lower bound: "Over --- But not over $23,750: 0.5" for single filers, and the same in the other columns. 26 U.S.C. 25B(b)(1) also sets the rate only by "not over" amounts. This PR sets the first threshold to -.inf, as other scales in the repo do (for example gov/ed/student_loans/repayment_assistance_plan/base_payment/rate.yaml).

Case (2025) Before After Form 8880 line 10
Single, AGI -$8,000, $1,000 IRA contribution $0 $500 $500
Joint, AGI -$1, $3,000 IRA contributions $0 $1,500 $1,500

Impact

Under current law the final savers_credit (line 12) does not change. The credit is nonrefundable, and a return with negative AGI has no income tax for it to offset. The change shows in savers_credit_potential and in any reform that makes the credit refundable or changes its limit.

Tests

Found by the engine differential in emmilco/us-tax-model.

🤖 Generated with Claude Code

The first bracket of gov.irs.credits.retirement_saving.rate.joint started at
$0, and a single-amount scale returns 0 below its first threshold, so
savers_credit_potential was $0 for a negative adjusted gross income. The
Form 8880 line 9 table's first row has no lower bound, and 26 U.S.C.
25B(b)(1) sets the rate only by "not over" amounts. The first threshold
is now -.inf.

Fixes #10538.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@PavelMakarchuk
PavelMakarchuk marked this pull request as ready for review October 29, 2026 16:54

@hua7450 hua7450 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving at 81318db. Thanks, Pavel.

The fix is right. 26 U.S.C. 25B(b)(1)(A) gives 50 percent when AGI "is not over" the first amount, and the Form 8880 line 9 table's first row has no lower bound. With -.inf as the first threshold, negative AGI takes 50% for every filing status and every year in the parameter history. Nothing changes at AGI of zero or above. The new scale has no uprating block, so the -.inf threshold is never uprated. I recomputed the three new cases by hand, and they match.

Optional nits:

  1. Test header and PR body. Both say 25B(b)(1) sets the rate "only by 'not over' amounts", but (B) to (D) use "over $X but not over $Y" and "over $50,000". Only (A), the 50% row, has no lower bound. Suggested wording: "26 U.S.C. 25B(b)(1)(A) gives 50 percent when AGI 'is not over' the first amount, with no lower bound, so a negative AGI takes the 50% rate."
  2. Impact paragraph. "A return with negative AGI has no income tax for it to offset" holds in this model, but not in general. The credit can offset AMT, and AMTI can be positive when AGI is negative (incentive stock options, for example). Saying "in this model" would make it accurate.
  3. Case names. The new cases could use the "Case N, ..." form that savers_credit_person.yaml uses.

Follow-ups, outside this PR (all are the same on main):

  • qualified_retirement_savings_contributions.yaml drops ABLE contributions from 2026, although P.L. 119-21 sec. 70116 kept them. From 2027 the credit should cover only ABLE contributions (SECURE 2.0 sec. 103 moves the rest to the Saver's Match), with a $2,100 cap. The joint.yaml thresholds also have no uprating after 2026. If uprating is added, attach it to brackets 2 to 4 only, because Core's rounding raises on -inf.
  • savers_credit_qualified_contributions subtracts only the person's own distributions. On a joint return, 25B(d)(2)(D) and Form 8880 line 4 also count the spouse's distributions.
  • The bands are keyed at statutory amount + 1 and looked up on AGI / adjustment, so a fractional AGI less than $1 over a "not over" amount keeps the lower band's rate. With -.inf now first, the bands could be keyed at the band tops with .calc(..., right=True).

@PavelMakarchuk
PavelMakarchuk merged commit 202b724 into main Oct 29, 2026
40 checks passed
@PavelMakarchuk
PavelMakarchuk deleted the fix-10538-savers-credit-negative-agi branch October 29, 2026 20:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Saver's credit rate is zero for negative AGI

2 participants