{"record":{"id":"33882010b3a6f80f","repo":"can1357/oh-my-pi","slug":"unknown-delivery-delivery-id","errorCode":null,"errorMessage":"unknown delivery {delivery_id}","messagePattern":"unknown delivery (.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"warning","filePath":"python/robomp/src/server.py","lineNumber":689,"sourceCode":"        request: Request,\n        payload: dict[str, Any] = Body(...),\n        x_robomp_token: str | None = Header(None, alias=\"X-Robomp-Replay-Token\"),\n    ) -> JSONResponse:\n        \"\"\"Stop a running event. The omp subprocess is killed; the row lands in\n        `failed` with `cancelled by operator` as the error.\n        \"\"\"\n        bag = request.app.state.bag\n        cfg: Settings = bag[\"settings\"]\n        _require_trigger_token(cfg, x_robomp_token)\n\n        delivery_id = payload.get(\"delivery_id\")\n        if not isinstance(delivery_id, str) or not delivery_id:\n            raise HTTPException(400, \"cancel requires 'delivery_id'\")\n\n        db: Database = bag[\"db\"]\n        event = db.get_event(delivery_id)\n        if event is None:\n            raise HTTPException(404, f\"unknown delivery {delivery_id}\")\n        if event.state != \"running\":\n            raise HTTPException(\n                409, f\"delivery {delivery_id} is {event.state}; only running deliveries can be cancelled\"\n            )\n\n        pool: WorkerPool = bag[\"pool\"]\n        fired = await pool.cancel_event(delivery_id)\n        log.info(\n            \"manual cancel\",\n            extra={\"delivery\": delivery_id, \"fired\": fired, \"state\": event.state},\n        )\n        return JSONResponse(\n            {\"delivery\": delivery_id, \"fired\": fired, \"previous_state\": event.state},\n            status_code=202,\n        )\n\n    @app.get(\"/events\")\n    async def events(request: Request, limit: int = 50) -> dict[str, Any]:","sourceCodeStart":671,"sourceCodeEnd":707,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/python/robomp/src/server.py#L671-L707","documentation":"FastAPI raises HTTP 404 with 'unknown delivery {delivery_id}' from POST /api/cancel when no event row with that delivery_id exists in the SQLite events table. The cancel endpoint first validates the delivery_id is a non-empty string (400 otherwise), then looks it up via db.get_event(); a miss means the id is not a real delivery this server ever received.","triggerScenarios":"POST /api/cancel with a delivery_id that was never recorded, a typo'd/copied-wrong id, an id from a different robomp instance (fresh /data volume or different deployment), or an id purged by database reset/retention.","commonSituations":"Operator copies a delivery id from GitHub's webhook log instead of from /events; the container was recreated with an empty /data volume so the SQLite rows are gone; typo in curl/dashboard invocation; pointing the dashboard at the wrong backend.","solutions":["List real ids with GET /events and use the delivery_id shown there (or click cancel in the dashboard, which uses ids from that listing).","Check you are hitting the same robomp instance that received the webhook (correct host/port, same docker compose project).","Verify the /data volume persists; a recreated container with an anonymous volume loses the events DB.","Re-run the task with POST /api/trigger (triage mode) instead of cancelling if the delivery never existed on this server."],"exampleFix":"// before\ncurl -X POST /api/cancel -d '{\"delivery_id\":\"abc-123\"}'  // 404 unknown delivery abc-123\n// after\nID=$(curl -s localhost:8080/events | jq -r '.events[] | select(.state==\"running\") | .delivery_id' | head -1)\ncurl -X POST /api/cancel -H 'Content-Type: application/json' -d \"{\\\"delivery_id\\\":\\\"$ID\\\"}\"","handlingStrategy":"validation","validationCode":"const res = await fetch('/events');\nconst { events } = await res.json();\nconst known = new Set(events.map(e => e.delivery_id));\nif (!known.has(deliveryId)) throw new Error(`unknown delivery ${deliveryId}: check /events`);","typeGuard":"function isDeliveryId(v: unknown): v is string {\n  return typeof v === 'string' && v.length > 0;\n}","tryCatchPattern":"try {\n  await api.cancel(deliveryId);\n} catch (e) {\n  if (e instanceof ApiError && e.status === 404) {\n    console.warn(`delivery ${deliveryId} not found; refresh the event list`);\n  } else throw e;\n}","preventionTips":["Always source delivery ids from GET /events or the dashboard, never from GitHub webhook logs.","Drive cancels through the dashboard UI, which lists live ids.","Keep the /data volume persistent so event rows survive container recreation.","Check you are targeting the same robomp deployment that received the webhook."],"tags":["http-404","rest-api","fastapi","invalid-id"],"backgroundTag":"resource-not-found-404","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}