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

  1. Send a JSON body with a non-empty string: {"delivery_id": "<id>"}
  2. Ensure Content-Type: application/json and that the body is actually transmitted
  3. Convert the delivery value to a string before sending
  4. 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

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


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/a62df6dc8dafecff. Report an issue: GitHub.