Skip to content

Bug: Parameter reforms to UC standard allowance are silently overridden by set_input in uc_reform scenario #1511

@MaxGhenis

Description

@MaxGhenis

Summary

Parameter-based reforms to Universal Credit standard allowance amounts are silently ignored because the hardcoded universal_credit_july_2025_reform scenario uses set_input() to override uc_standard_allowance values after user reforms are applied.

Reproduction

from policyengine_uk import Microsimulation

# Try to set UC standard allowance to £500/month via parameter reform
sim = Microsimulation(reform={
    "gov.dwp.universal_credit.standard_allowance.amount.SINGLE_OLD": {
        "2026-01-01.2100-12-31": 500
    }
})

# The parameter is changed in the tax_benefit_system...
# ...but uc_standard_allowance for 2026-2029 has already been overwritten
# by set_input() in the UC rebalancing reform, so the formula never runs
# and the parameter change has no effect.

Root cause

In simulation.py line 156-158, universal_credit_july_2025_reform.simulation_modifier(self) is called unconditionally during __init__, after data is loaded but before user scenario modifiers run. This calls add_universal_credit_reform() in scenarios/uc_reform.py, which:

  1. Calculates uc_standard_allowance for each year 2026-2029 using the baseline parameters
  2. Applies the rebalancing uplift
  3. Calls sim.set_input("uc_standard_allowance", year, new_value) to inject these values directly

When set_input() is called on a variable, the simulation caches that as a known input. Later, when the variable is requested, the cached input value is returned instead of running the formula. Since the formula is the only thing that reads from the parameter tree, the user's parameter reform is effectively invisible.

The user's scenario modifier runs at lines 193-197, after the UC reform has already injected values via set_input. Even though the parameter tree is correctly updated, the formula for uc_standard_allowance is never invoked because set_input values take precedence.

Expected behavior

A parameter reform to gov.dwp.universal_credit.standard_allowance.amount.* should be reflected in uc_standard_allowance calculations, with the UC rebalancing uplift applied on top of the reformed values (or skipped, depending on policy intent).

Proposed fix

In add_universal_credit_reform(), before calling set_input("uc_standard_allowance", ...), check whether the user's reform modifies any UC standard allowance parameters. If so, skip the set_input override for uc_standard_allowance so the formula can pick up the reformed parameter values.

Alternatively, the UC reform could be restructured to modify parameters (the uplift amounts) rather than using set_input to bypass the formula entirely.

Impact

This is a silent data correctness bug. Users who reform UC standard allowance parameters get results that look correct but are actually unchanged from baseline for years 2026-2029. There is no error or warning.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions