{"record":{"id":"fdfb68b9bde6d416","repo":"paperclipai/paperclip","slug":"opencode-run-attach-invalid","errorCode":"opencode_run_attach_invalid","errorMessage":"opencode_run_attach_invalid","messagePattern":"opencode_run_attach_invalid","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/src/drivers/opencode/opencode-server-driver.ts","lineNumber":509,"sourceCode":"          opencodeVersion: input.runtime.version,\n        },\n      },\n      { itemId: `${input.providerSessionId}:model` },\n    );\n  }\n\n  ids() {\n    return {\n      driverSessionId: this.#providerSessionId,\n      providerSessionId: this.#providerSessionId,\n      displayId: this.#providerSessionId,\n    };\n  }\n\n  attachRun(input: { runId: string }): void {\n    if (this.#activeTurnId !== null)\n      throw new Error(\"opencode_run_attach_busy\");\n    if (!input.runId) throw new Error(\"opencode_run_attach_invalid\");\n    this.#runId = input.runId;\n    this.#result = null;\n    this.#resultFingerprint = null;\n    this.#resultCallId = null;\n    this.#resultTurnId = null;\n    this.#semanticResultTextBoundary = null;\n    this.#semanticResultProviderMessageId = null;\n    this.#lastNonTerminalToolSourceSeq = 0;\n    this.#completedTextPartIds.clear();\n    this.#completedReasoningPartIds.clear();\n    this.#completedTextParts.length = 0;\n    this.#terminalTurns.clear();\n    this.#sendFullContext = false;\n    this.#emit(\"run.attached\", { runId: input.runId, sameSession: true });\n  }\n\n  events(): AsyncIterable<PrpEvent> {\n    return this.#events;","sourceCodeStart":491,"sourceCodeEnd":527,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/src/drivers/opencode/opencode-server-driver.ts#L491-L527","documentation":"After the busy check, attachRun validates that input.runId is non-empty; an empty string, null, or undefined throws opencode_run_attach_invalid because the driver cannot bind result tracking without a run identifier.","triggerScenarios":"Calling attachRun({ runId: '' }) or with runId omitted — usually a runner bug where the run record wasn't created/persisted before attaching, or an id field read from an API response that was undefined.","commonSituations":"Database row not yet assigned an id, destructuring a missing field from a run payload, template string defaults collapsing to empty string, migration gaps leaving runs without identifiers.","solutions":["Create/resolve the run id before attachRun and assert it's a non-empty string at the call site.","Check upstream code that constructs the run record — ensure the id is generated and returned.","Validate run payloads at the boundary (schema/zod) so missing ids fail earlier with a clear message.","Pass a deterministic id (e.g. uuid) if the caller legitimately has no persistence-backed id yet."],"exampleFix":"// before\ndriver.attachRun({ runId: run?.id ?? '' }); // silently empty -> throws\n// after\nif (!run?.id) throw new Error(`run record missing id: ${JSON.stringify(run)}`);\ndriver.attachRun({ runId: run.id });","handlingStrategy":"validation","validationCode":"const assertRunId = (id: string | undefined): string => { if (typeof id !== 'string' || id.length === 0) throw new Error('attachRun requires a non-empty runId'); return id; };","typeGuard":"const isRunId = (v: unknown): v is string => typeof v === 'string' && v.length > 0;","tryCatchPattern":"try { driver.attachRun({ runId }); } catch (e) { if ((e as Error).message === 'opencode_run_attach_invalid') { console.error('runId was empty; run record likely unpersisted', { runId }); throw new Error('Create and persist the run record before attaching', { cause: e }); } throw e; }","preventionTips":["Validate run payloads with a schema so missing ids fail at the boundary","Generate a deterministic uuid run id if persistence lags behind attach","Never default runId to '' with ?? ''; fail loudly instead","Ensure the run-creation API returns the id before the runner proceeds"],"tags":["opencode","validation","arguments","state"],"backgroundTag":"empty-required-field","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"}