You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
PUT /v1/workspaces/{workspaceId}/jobs/{jobId}/status rejects all valid bodies (body-parser strict mode vs bare-string schema) #1158
The job status update endpoint PUT /v1/workspaces/{workspaceId}/jobs/{jobId}/status returns 400 for every possible request body. It is currently unusable over HTTP.
Root cause
Two things collide:
apps/api/src/server.ts mounts express.json({ limit: "100mb" }), which uses body-parser's default strict: true — only {…} (objects) and […] (arrays) are accepted at the top level.
The endpoint's OpenAPI request body is a bare JobStatus string (apps/api/openapi/paths/jobs.jsonnet → schemaRef('JobStatus')), and the handler reads req.body directly as that string (apps/api/src/routes/v1/workspaces/jobs.ts, updateJobStatus → const { body: oapiStatus } = req).
So there is no body that works:
"successful" (the documented body) → top-level scalar → body-parser throws SyntaxError: Unexpected token '"' before the handler runs.
successful (unquoted) → not valid JSON → same class of error.
{ "status": "successful" } → passes strict mode but fails the handler's oapiToDbStatus[body] lookup → 400 Invalid job status.
Reproduction
curl -s -X PUT "$API/api/v1/workspaces/$WS/jobs/$JOB/status" \
-H "x-api-key: $KEY" -H 'content-type: application/json' -d '"successful"'# {"message":"Unexpected token '\"', \"\"successful\"\" is not valid JSON","code":"SyntaxError",...}
Why it has gone unnoticed
Job status is updated today via paths that bypass this endpoint:
the workspace-engine writes the DB directly (UpdateJobStatus query), and
the GitHub / Terraform Cloud / Argo webhooks write the DB directly.
Nothing currently drives this HTTP endpoint, so the breakage has been silent.
Why it matters now
The pull-based job agent (#1153 / PR #1157) has external agents report status over HTTP via this endpoint — it is the "report status back" half of the pull contract. The endpoint must work for pull agents to function.
Proposed fix
Change the request body from a bare string to an object and read it accordingly:
Handler: const { status } = req.body instead of const oapiStatus = req.body
Object bodies pass strict mode, it's conventional REST, and since there are no working callers today there is nothing to break. (Rejected alternatives: express.json({ strict: false }) globally — too broad; a per-route text parser — hacky.)
Regenerate the API OpenAPI types after the schema change.
Update generated openapi.json and openapi.ts types
Commit and push changes
Changes made
The endpoint was broken because express.json strict mode rejects bare top-level strings, but the schema declared the request body as a bare JobStatus string.
apps/api/openapi/paths/jobs.jsonnet — changed request body from schemaRef('JobStatus') to { type: object, required: ["status"], properties: { status: JobStatus } }
Activity
adityachoudhari26 commentedon Jun 3, 2026
@claude fix this
claude commentedon Jun 3, 2026
Claude finished @adityachoudhari26's task in 2m 20s —— View job •
claude/issue-1158-20260603-1819• Create PR ➔Fixing job status update endpoint
jobs.jsonnetjobs.tsto readreq.body.statusopenapi.jsonandopenapi.tstypesChanges made
The endpoint was broken because
express.jsonstrict mode rejects bare top-level strings, but the schema declared the request body as a bareJobStatusstring.apps/api/openapi/paths/jobs.jsonnet— changed request body fromschemaRef('JobStatus')to{ type: object, required: ["status"], properties: { status: JobStatus } }apps/api/src/routes/v1/workspaces/jobs.ts— changedconst { body: oapiStatus } = reqtoconst { status: oapiStatus } = req.bodyapps/api/openapi/openapi.jsonandapps/api/src/types/openapi.ts— updated generated artifacts to match the new schemaNow the endpoint accepts: