{"record":{"id":"ce1ccf4ac8560819","repo":"paperclipai/paperclip","slug":"opencode-health-response-omitted-a-semantic-versio","errorCode":null,"errorMessage":"OpenCode health response omitted a semantic version","messagePattern":"OpenCode health response omitted a semantic version","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/src/drivers/opencode/opencode-server-driver.ts","lineNumber":2018,"sourceCode":"        pid: child.pid,\n        processGroupId:\n          globalThis.process.platform === \"win32\" || !isolateProcessGroup\n            ? null\n            : child.pid,\n        startedAt: new Date().toISOString(),\n      });\n    const baseUrl = `http://127.0.0.1:${port}`;\n    const health = await waitForHealth(\n      baseUrl,\n      authHeader,\n      input.options.fetch ?? globalThis.fetch,\n      child,\n      () => diagnostics,\n      input.trace,\n    );\n    const version = text(record(health).version);\n    if (!/^\\d+\\.\\d+\\.\\d+$/.test(version))\n      throw new Error(\"OpenCode health response omitted a semantic version\");\n    const qualifiedComparison = compareVersion(\n      version,\n      QUALIFIED_OPENCODE_VERSION,\n    );\n    if (qualifiedComparison !== 0) {\n      throw new Error(\n        `OpenCode ${version} is not the question-conformance-qualified ${QUALIFIED_OPENCODE_VERSION}`,\n      );\n    }\n    return {\n      baseUrl,\n      authHeader,\n      version,\n      permissionMode: input.options.permissionMode ?? \"allow\",\n      process: child,\n      bridge,\n      trace: input.trace,\n      sensitiveValues: [","sourceCodeStart":2000,"sourceCodeEnd":2036,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/src/drivers/opencode/opencode-server-driver.ts#L2000-L2036","documentation":"Thrown during startup when the OpenCode server health endpoint response has a 'version' field that does not match the required semver pattern ^\\d+\\.\\d+\\.\\d$. The driver pins behavior to an exact qualified version, so it refuses to proceed with an unparseable or missing version string.","triggerScenarios":"Health response 'version' is missing, empty, or non-semver — e.g. 'v1.2.3' (leading v), '1.2', '1.2.3-beta.1', or a dev build string like 'main+abc123'.","commonSituations":"Pointing the driver at a dev build or a fork of OpenCode that reports a non-plain-semver version; a proxy returning an HTML error page that was parsed loosely; server upgrade changing the version format.","solutions":["Run the OpenCode server binary whose health endpoint reports a plain semver (e.g. 1.2.3) — check the health endpoint output with curl.","If using a dev/nightly build, switch to the released build matching the qualified version.","Check whether a proxy/gateway is intercepting the health request and returning an unexpected payload.","If the version format legitimately changed upstream, update the driver's validation regex and qualified-version comparison."],"exampleFix":"// before (server reports v1.2.3)\n\"version\": \"v1.2.3\" // fails /^\\d+\\.\\d+\\.\\d+$/\n\n// after\n\"version\": \"1.2.3\" // passes; or strip the leading 'v' before validating","handlingStrategy":"validation","validationCode":"const { version } = await (await fetch(`${baseUrl}/health`)).json();\nif (!/^\\d+\\.\\d+\\.\\d+$/.test(version)) throw new Error(`Non-semver OpenCode version: ${version}`);","typeGuard":"function isPlainSemver(v: unknown): v is string {\n  return typeof v === \"string\" && /^\\d+\\.\\d+\\.\\d+$/.test(v);\n}","tryCatchPattern":"try {\n  await startDriver();\n} catch (e) {\n  if (e instanceof Error && e.message.includes(\"omitted a semantic version\")) {\n    // curl the health endpoint, inspect raw version, fix binary or proxy\n  }\n}","preventionTips":["Use released OpenCode builds, not dev/nightly builds with non-semver version strings","curl the health endpoint after install to confirm the version format","Ensure no proxy rewrites the health response body"],"tags":["version-check","validation","health-check"],"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"}