Summary
SimulationService.update_simulation always appends api_version = ? to update_fields, so the "no fields supplied" guard in both the service and the route handler is unreachable. A PATCH with an empty body (or a body with only unknown keys) silently rewrites api_version with no other user intent.
Location
- Service:
policyengine_api/services/simulation_service.py:478-500
- Route:
policyengine_api/routes/simulation_routes.py:191-192
What goes wrong
Service (excerpt):
update_fields = []
update_values = []
if status is not None:
update_fields.append("status = ?")
update_values.append(status)
if output is not None:
update_fields.append("output = ?")
update_values.append(output)
if error_message is not None:
update_fields.append("error_message = ?")
update_values.append(error_message)
update_fields.append("api_version = ?")
update_values.append(api_version)
if not update_fields: # always False — api_version was just appended
print("No fields to update")
return False
Route (excerpt):
if not success:
raise BadRequest("No fields to update")
The route handler's BadRequest("No fields to update") can therefore never fire. A client PATCH with {} still runs UPDATE simulation SET api_version = ? WHERE ..., which (a) mutates a row the client didn't ask to mutate and (b) masks the bad input.
Suggested fix
Only stamp api_version when there is at least one real user-supplied field, and validate earlier:
if status is None and output is None and error_message is None:
return False
# ... build update_fields for real inputs ...
update_fields.append("api_version = ?")
update_values.append(api_version)
Or reject empty payloads in the route before calling the service.
Severity
Medium.
Summary
SimulationService.update_simulationalways appendsapi_version = ?toupdate_fields, so the "no fields supplied" guard in both the service and the route handler is unreachable. A PATCH with an empty body (or a body with only unknown keys) silently rewritesapi_versionwith no other user intent.Location
policyengine_api/services/simulation_service.py:478-500policyengine_api/routes/simulation_routes.py:191-192What goes wrong
Service (excerpt):
Route (excerpt):
The route handler's
BadRequest("No fields to update")can therefore never fire. A client PATCH with{}still runsUPDATE simulation SET api_version = ? WHERE ..., which (a) mutates a row the client didn't ask to mutate and (b) masks the bad input.Suggested fix
Only stamp
api_versionwhen there is at least one real user-supplied field, and validate earlier:Or reject empty payloads in the route before calling the service.
Severity
Medium.