can1357/oh-my-pi · warning · HTTPException
cancel requires 'delivery_id'
Error message
cancel requires 'delivery_id'
What it means
The cancel endpoint requires a delivery id and raises HTTP 400 'cancel requires delivery_id' when the request body lacks one. Cancelling targets a specific running event; without a non-string delivery_id (or an empty one) there is nothing to cancel, and unlike retry there is no issue-reference alternative, so the request is rejected immediately after token authentication (`_require_trigger_token`).
Source
Thrown at python/robomp/src/server.py:684
status_code=202,
)
@app.post("/api/cancel")
async def api_cancel(
request: Request,
payload: dict[str, Any] = Body(...),
x_robomp_token: str | None = Header(None, alias="X-Robomp-Replay-Token"),
) -> JSONResponse:
"""Stop a running event. The omp subprocess is killed; the row lands in
`failed` with `cancelled by operator` as the error.
"""
bag = request.app.state.bag
cfg: Settings = bag["settings"]
_require_trigger_token(cfg, x_robomp_token)
delivery_id = payload.get("delivery_id")
if not isinstance(delivery_id, str) or not delivery_id:
raise HTTPException(400, "cancel requires 'delivery_id'")
db: Database = bag["db"]
event = db.get_event(delivery_id)
if event is None:
raise HTTPException(404, f"unknown delivery {delivery_id}")
if event.state != "running":
raise HTTPException(
409, f"delivery {delivery_id} is {event.state}; only running deliveries can be cancelled"
)
pool: WorkerPool = bag["pool"]
fired = await pool.cancel_event(delivery_id)
log.info(
"manual cancel",
extra={"delivery": delivery_id, "fired": fired, "state": event.state},
)
return JSONResponse(
{"delivery": delivery_id, "fired": fired, "previous_state": event.state},View on GitHub (pinned to 9690622007)
Solutions
- Send a JSON body with a non-empty string: {"delivery_id": "<id>"}
- Ensure Content-Type: application/json and that the body is actually transmitted
- Convert the delivery value to a string before sending
- Include the trigger token header (x-robomp-token) so auth passes before validation — though this error specifically means the id field itself is missing
Example fix
// before
await fetch('/cancel', { method: 'POST', body: JSON.stringify({ id: 42 }) });
// after
await fetch('/cancel', { method: 'POST', headers: { 'Content-Type': 'application/json', 'x-robomp-token': token }, body: JSON.stringify({ delivery_id: String(evt.deliveryId) }) }); Defensive patterns
Strategy: validation
Validate before calling
// Ensure a non-empty string delivery_id is present before calling cancel
if (typeof deliveryId !== 'string' || deliveryId.length === 0) {
throw new Error('cancel needs a non-empty string delivery_id');
} Type guard
function isDeliveryId(v: unknown): v is string {
return typeof v === 'string' && v.trim().length > 0;
} Try / catch
try {
await api.cancel({ delivery_id: deliveryId });
} catch (err) {
if (err.status === 400 && /cancel requires/.test(err.message)) {
logger.error('cancel call missing delivery_id', { deliveryId });
} else throw err;
} Prevention
- Use the exact key 'delivery_id' (not 'id' or 'delivery') in the cancel body
- Send string values — numeric ids are rejected
- Always attach the body and Content-Type: application/json to cancel requests
- Centralize cancel in one client helper that validates the id and token header before sending
When it happens
Trigger: POSTing to the cancel endpoint with a body missing 'delivery_id', an empty string value, a non-string value (number/null), or a body that failed to parse into `payload` — checked at server.py:684: `if not isinstance(delivery_id, str) or not delivery_id`.
Common situations: Client sending the id under a different key name ('id', 'delivery'); forgetting the JSON body; frameworks dropping the body on DELETE-style calls; passing a numeric database id where the string delivery id is expected.
Understand the failure class
Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.
Related errors
- retry requires 'delivery_id' or 'issue'
- {str(exc)} (ManualTriageError)
- Missing required parameter 'code' for action 'run'.
- ${params.op} requires name
- start requires application
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/a62df6dc8dafecff.
Report an issue: GitHub.