{"record":{"id":"f324cfb3e9523d00","repo":"paperclipai/paperclip","slug":"opencode-session-creation-omitted-its-id","errorCode":null,"errorMessage":"OpenCode session creation omitted its id","messagePattern":"OpenCode session creation omitted its id","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/src/drivers/opencode/opencode-server-driver.ts","lineNumber":322,"sourceCode":"        const fetcher = this.#options.fetch ?? globalThis.fetch;\n        let providerSessionId =\n          snapshot?.providerSessionId ?? snapshot?.driverSessionId ?? null;\n        if (providerSessionId !== null) {\n          const existing = await api(\n            fetcher,\n            runtime,\n            `/session/${encodeURIComponent(providerSessionId)}`,\n          );\n          if (!isRecord(existing) || text(existing.id) !== providerSessionId)\n            throw new Error(\"OpenCode resumed a different session\");\n        } else {\n          const created = await api(fetcher, runtime, \"/session\", {\n            method: \"POST\",\n            body: JSON.stringify({ title: `Paperclip ${input.runId}` }),\n          });\n          providerSessionId = text(record(created).id);\n          if (!providerSessionId)\n            throw new Error(\"OpenCode session creation omitted its id\");\n        }\n        session = new OpenCodeHarnessSession({\n          runtime,\n          fetcher,\n          runId: input.runId,\n          normalizedSessionId: input.normalizedSessionId,\n          providerSessionId,\n          workingDirectory: cwd,\n          runnerInstanceId:\n            this.#options.runnerInstanceId ??\n            `paperclip-opencode-${input.runId}`,\n          model: this.#options.model,\n          taskEnvelope:\n            this.#options.taskEnvelope ??\n            createCodexTaskEnvelope({\n              objective: \"Complete the supplied task.\",\n            }),\n          systemInstructions:","sourceCodeStart":304,"sourceCodeEnd":340,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/src/drivers/opencode/opencode-server-driver.ts#L304-L340","documentation":"When creating a fresh OpenCode session via POST /session, the driver extracts the id from the response with text(record(created).id) and throws this error if the resulting id is empty/undefined — the server responded but did not include the required session identifier.","triggerScenarios":"POST /session returns 2xx with a body lacking an id field, an error-shaped body, or a record whose id is not a string — e.g. incompatible OpenCode server version or a proxy intercepting the response.","commonSituations":"Version mismatch between driver and OpenCode server API, gateway returning HTML/error JSON without id, server bug omitting id, hitting the wrong endpoint (proxy rewriting /session).","solutions":["Call POST /session manually and inspect the response body — confirm it contains a non-empty id.","Upgrade the OpenCode server to the API version the driver expects (contract drift on the session record shape).","Check for proxies/middleware rewriting the /session response and bypass them.","Log the full created payload; if it's an error object, surface the server's real error instead of the missing id."],"exampleFix":"// before\nconst created = await api(fetcher, runtime, '/session', { method: 'POST', body: JSON.stringify({ title: `Paperclip ${input.runId}` }) });\n// after (assert shape early)\nconst created = await api(fetcher, runtime, '/session', { method: 'POST', body: JSON.stringify({ title: `Paperclip ${input.runId}` }) });\nif (!isRecord(created) || typeof created.id !== 'string' || !created.id)\n  throw new Error(`OpenCode /session returned no id: ${JSON.stringify(created)}`);","handlingStrategy":"retry","validationCode":"const probe = await fetch(`${baseUrl}/session`, { method: 'POST', body: JSON.stringify({ title: 'healthcheck' }) });\nconst probeBody = await probe.json();\nif (typeof probeBody?.id !== 'string' || !probeBody.id) throw new Error(`OpenCode server /session shape invalid: ${JSON.stringify(probeBody)}`);","typeGuard":"const hasSessionId = (v: unknown): v is { id: string } => isRecord(v) && typeof v.id === 'string' && v.id.length > 0;","tryCatchPattern":"try { await openSession(input); } catch (e) { if ((e as Error).message === 'OpenCode session creation omitted its id') { await assertOpenCodeServerCompatible(); await openSession(input); } else throw e; }","preventionTips":["Run a /session shape health check at driver startup","Pin the OpenCode server version to one the driver tests against","Bypass or audit proxies that rewrite API responses","Fail fast on non-2xx/error-shaped bodies before extracting id"],"tags":["opencode","session","http","api-contract"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}