Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Salary sacrifice above the April 2029 NI cap raises adjusted net income, but HMRC says the cap leaves ANI unchanged

Open
#2,173 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
57/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
python, yaml
Domain
backend, databases

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

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-uk

All issues in PolicyEngine/policyengine-uk

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.