Summary
billable_units is forwarded from result.billableUnits without coercion in lib/runs/execute.ts. When that value is undefined (non-blocking/queued executions or older gateway responses), JSON.stringify omits the key even though the intended contract is number | null and the field should always be present.
Caught on main by a follow-up review of code that has not changed since the last PR review.
Location
lib/runs/execute.ts (~line 252):
billable_units: result.billableUnits,
Contract tests already assert the field is present as number | null:
tests/contracts/run-execution.test.ts — "never repeats paid execution when terminal storage fails" expects billable_units to be null
"forwards billable_units from the gateway result" expects a numeric value when the gateway provides one
There is no coverage for the missing/undefined case.
Proposed fix
Coerce missing units to null before putting them on the payload, e.g. result.billableUnits ?? null.
Add a contract test where the gateway result omits billableUnits (queued / non-blocking / older response) and assert the JSON payload still includes "billable_units": null.
Test plan
Summary
billable_unitsis forwarded fromresult.billableUnitswithout coercion inlib/runs/execute.ts. When that value isundefined(non-blocking/queued executions or older gateway responses),JSON.stringifyomits the key even though the intended contract isnumber | nulland the field should always be present.Caught on
mainby a follow-up review of code that has not changed since the last PR review.Location
lib/runs/execute.ts(~line 252):Contract tests already assert the field is present as
number | null:tests/contracts/run-execution.test.ts—"never repeats paid execution when terminal storage fails"expectsbillable_unitsto benull"forwards billable_units from the gateway result"expects a numeric value when the gateway provides oneThere is no coverage for the missing/
undefinedcase.Proposed fix
Coerce missing units to
nullbefore putting them on the payload, e.g.result.billableUnits ?? null.Add a contract test where the gateway result omits
billableUnits(queued / non-blocking / older response) and assert the JSON payload still includes"billable_units": null.Test plan
undefined/ omittedbillableUnitstonullin the execute payload