Salary sacrifice above the April 2029 NI cap raises adjusted net income, but HMRC says the cap leaves ANI unchanged
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 57/100
Research direction
Trace salary_sacrifice_returned_to_income, employee_pension_contributions, pension_contributions_relief and adjusted_net_income in the relevant UK policy variables, then find the YAML tests for this case. Check the 2029-30 behavior against the issue’s example: ANI should remain at £97,000 less the broad-base haircut, income tax should match 2028-29 rules, and NI should apply to £8,000 more earnings.
Written by the indexing model from the issue text.
Description
What happens. From 6 April 2029, gov.hmrc.national_insurance.salary_sacrifice_pension_cap (£2,000) makes pension salary sacrifice above the cap subject to Class 1 NI. policyengine-uk models this by adding the excess (salary_sacrifice_returned_to_income) to employment_income. The same amount is added to employee_pension_contributions, and pension_contributions_relief gives the income tax relief. That relief enters allowances after adjusted_net_income, so ANI rises by the full excess.
What the law says. HMRC's policy paper, Salary sacrifice reform for pension contributions effective from 6 April 2029, says the measure changes Class 1 National Insurance only. It does not change salary sacrifice's effect on adjusted net income, and the paper names Tax-Free Childcare among the schemes unaffected.
Example (policyengine-uk 2.102.3). One parent with £97,000 employment income (employment_income_before_lsr) after £10,000 of pension salary sacrifice, and a two-year-old:
| 2028-29 | 2029-30 | |
|---|---|---|
salary_sacrifice_returned_to_income |
£0 | £8,000 |
adjusted_net_income |
£97,000.00 | £104,844.80 |
extended_childcare_entitlement_meets_income_requirements |
True | False |
tax_free_childcare_meets_income_requirements |
True | False |
So the parent loses the 30 funded hours and Tax-Free Childcare in 2029-30, although under the measure their ANI stays below £100,000. The personal allowance taper and the High Income Child Benefit Charge, which both read ANI, are affected in the same way.
Suggested fix. For income tax the sacrifice stays a sacrifice under the measure; only Class 1 NI changes. So the excess above the cap should enter NI-able earnings only, not employment_income, employee_pension_contributions or pension_contributions_relief. Excluding it from ANI alone is not enough: the model also gives the excess as pension relief, so deducting it again from ANI double-counts it. In a quick test, income tax fell by about £4,200 against the correct figure. A YAML test with the case above should hold ANI at £97,000 (less the model's broad-base haircut) in 2029-30, with income tax unchanged from 2028-29 rules and NI charged on £8,000 more earnings.
Found while costing the removal of the £100,000 childcare limit (PolicyEngine/uk-childcare-100k-threshold#1), which applies this correction locally until it is fixed upstream.
- Dominant language
- Python
- Stars
- 51
- Forks
- 34
- Avg merge
- 2d 13h
- Merged PRs (30d)
- 177
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from PolicyEngine/policyengine-uk
-
Personal allowance for 2016-17 is £10,600; it was £11,000Possibly taken @juaristi22 claimed this 1 day ago. Open
Difficulty 1/5 1-3 hours Newbie friendliness 84/100
PolicyEngine/policyengine-uk#2359 · 1 assignee ·
Maintainers usually reply within 1 day
-
Northern Ireland business rates statistic is twice the OBR NI line: regional vs district ratesPossibly taken A pull request linked to this issue is open or already merged. Open
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
PolicyEngine/policyengine-uk#2343 ·
Maintainers usually reply within 1 day
-
Wealth and consumption shares divide by a weighted total that can be zeroPossibly taken @juaristi22 claimed this 1 day ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
PolicyEngine/policyengine-uk#2296 ·
Maintainers usually reply within 1 day
-
Childcare funding rates are CPI-uprated 2024-25 values, below DfE's published 2025-26 and 2026-27 ratesPossibly taken A pull request linked to this issue is open or already merged. Open
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
PolicyEngine/policyengine-uk#2183 ·
Maintainers usually reply within 1 day
-
Follow-ups from #2160: qualifying-age docstring, UC work-related groups property-file speed, changelog fragment examplePossibly taken A pull request linked to this issue is open or already merged. Open
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
PolicyEngine/policyengine-uk#2162 ·
Maintainers usually reply within 1 day
All issues in PolicyEngine/policyengine-uk
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 64/100
aws-samples/sample-per-model-bedrock#295 ·
Maintainers usually reply within 1 day
-
Difficulty 1/5 Under an hour Newbie friendliness 76/100
pyrevitlabs/pyRevit#3792 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 69/100
zephyrproject-rtos/reqmgmt#177 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
polarsource/polar#15580 ·
Maintainers usually reply within 1 day
-
Difficulty 1/5 Under an hour Newbie friendliness 85/100
521xueweihan/HelloGitHub#4011 ·