PolicyEngine / PolicyEngine/policyengine-uk
Benefit cap applies to 2x too many households (5.3% of UC vs 1.6% administrative)
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 50
- Forks
- 33
- Avg merge
- 20h 58m
- Merged PRs (30d)
- 14
Description
Summary
The model caps 222k UC households (5.30% of its UC caseload). DWP's administrative count is 111k (1.60%) at November 2025. That is 2.0x the count and 3.3x the rate, and it is broad-based rather than concentrated.
Found while trying to reproduce JRF's protected minimum floor estimate with the deductions module from #1815. It is a pre-existing benefit cap problem, not a deductions one, but it dominates that reform: 99% of the floor's modelled cost comes from benefit-capped households.
Enhanced FRS 2023/24 v1.40.3, simulated 2026.
Evidence
| model | DWP admin (Nov 2025) | |
|---|---|---|
| UC households capped | 222k | 111k |
| share of UC households | 5.30% | 1.60% |
| London capped rate | 9.62% | 3.30% |
| non-London capped rate | 4.51% | — |
| capped households with children | 68.4% | 80% |
Two things stand out. The over-capping is roughly 3x in London and outside it, so it is not a regional artefact. And our capped population is too childless — 31.6% without children against 20% in the admin data — which points at single adults, who face the lower cap (GBP 14,753 outside London) and are therefore easiest to tip over.
The excess over the cap is often marginal: p10 is GBP 82/yr and the median GBP 2,733/yr, so a systematic overstatement of capped benefit amounts would push many households over the line.
Ruled out
- Cap levels are correct. GBP 22,020 / 25,323 / 14,753 / 16,967, frozen since April 2023 and unchanged for 2026/27, verified against DWP benefit and pension rates 2026/27.
- Missing exemptions explain under 10% of the excess. Measured directly against the capped population.
- The earnings test's net basis is right. gov.uk specifies earnings after tax and National Insurance, which is what the code does.
- The UC childcare costs element is not an exemption (it is not on the gov.uk list), so its absence is correct.
Defects found along the way
These are real but individually small; none closes the gap.
- Armed Forces Independence Payment is a statutory exemption and is not applied. The variable
armed_forces_independence_paymentexists (variables/gov/dwp/afip.py) but is never referenced byis_benefit_cap_exempt_health_disability, which checksafcsonly. - Exempting benefits with no model variable at all: Guardian's Allowance, Adult Disability Payment, Child Disability Payment, Scottish Adult DLA, Pension Age Disability Payment, war pensions and War Widow's/Widower's Pension. The Scottish disability payments matter structurally, since Scotland has migrated PIP/DLA caseloads onto ADP/CDP — those households are currently capped when they should be exempt.
- The 9-month grace period is not modelled. 84% of capped units have zero earnings, so this bounds the grace-period effect at roughly 15% of the excess, but it is a real omission and an annual model handles it badly.
- The earnings threshold is hardcoded and stale:
earnings_threshold = 10_152(GBP 846/month) inis_benefit_cap_exempt_earnings, against GBP 881/month on gov.uk today. It should be a parameter with dated values. Note the sign: correcting it upward increases capping, so it is not a candidate cause of this bug. - Dead code.
is_benefit_cap_exempt_earningsandis_benefit_cap_exempt_othereach compute ~40 lines of qualifying-benefit variables that are then discarded — copy-paste fromis_benefit_cap_exempt_health_disability, whose return value is the only one that uses them. Both files return a single unrelated expression.
Leading hypotheses for the remaining gap
- Capped benefit amounts overstated, most likely housing. The cap binds on
universal_credit_pre_benefit_cap+housing_benefit_pre_benefit_cap; if modelled housing entitlement runs high, households cross the cap that would not in reality. The marginal excess distribution is consistent with this. - UC caseload composition. The model has 4.22m UC benefit units against ~7.2m administrative (PolicyEngine/policyengine-uk-data#452). If the ~3m missing households are disproportionately low-entitlement in-work claimants, the capped share inflates mechanically. This explains the rate gap but not the 2x absolute count.
- Annualisation. The cap is a monthly test; applying it to annual totals mis-scores households with variable income within the year.
Why it matters
For JRF-style protected floor analysis (#1814), the floor limits combined deductions and benefit cap reductions, so this error passes through almost undamped:
| PolicyEngine UK | JRF (IPPR TBM v02_78) | |
|---|---|---|
| cost | GBP 899m | GBP 340m |
| families gaining | 257k | ~90k |
| mean gain | GBP 67/wk | ~GBP 75/wk |
The mean per-family gain lands close, which is what you would expect if the per-household mechanics are right and the population is wrong. Until this is fixed, PolicyEngine UK cannot be used for benefit-cap-interacting reform estimates.
Contributor 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.
Research direction
Start by tracing the benefit-cap calculation, including universal_credit_pre_benefit_cap, housing_benefit_pre_benefit_cap, and the exemption functions. Inspect variables/gov/dwp/afip.py and compare the modelled capped population with the cited DWP figures. Done means identifying and fixing the cause of the excess cap rate, then confirming the results against the reported benchmarks.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100