paperclipai/paperclip · error

OpenCode health response omitted a semantic version

Error message

OpenCode health response omitted a semantic version

What it means

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.

Source

Thrown at packages/paperclip-runner/src/drivers/opencode/opencode-server-driver.ts:2018

        pid: child.pid,
        processGroupId:
          globalThis.process.platform === "win32" || !isolateProcessGroup
            ? null
            : child.pid,
        startedAt: new Date().toISOString(),
      });
    const baseUrl = `http://127.0.0.1:${port}`;
    const health = await waitForHealth(
      baseUrl,
      authHeader,
      input.options.fetch ?? globalThis.fetch,
      child,
      () => diagnostics,
      input.trace,
    );
    const version = text(record(health).version);
    if (!/^\d+\.\d+\.\d+$/.test(version))
      throw new Error("OpenCode health response omitted a semantic version");
    const qualifiedComparison = compareVersion(
      version,
      QUALIFIED_OPENCODE_VERSION,
    );
    if (qualifiedComparison !== 0) {
      throw new Error(
        `OpenCode ${version} is not the question-conformance-qualified ${QUALIFIED_OPENCODE_VERSION}`,
      );
    }
    return {
      baseUrl,
      authHeader,
      version,
      permissionMode: input.options.permissionMode ?? "allow",
      process: child,
      bridge,
      trace: input.trace,
      sensitiveValues: [

View on GitHub (pinned to 01ad858492)

Solutions

  1. Run the OpenCode server binary whose health endpoint reports a plain semver (e.g. 1.2.3) — check the health endpoint output with curl.
  2. If using a dev/nightly build, switch to the released build matching the qualified version.
  3. Check whether a proxy/gateway is intercepting the health request and returning an unexpected payload.
  4. If the version format legitimately changed upstream, update the driver's validation regex and qualified-version comparison.

Example fix

// before (server reports v1.2.3)
"version": "v1.2.3" // fails /^\d+\.\d+\.\d+$/

// after
"version": "1.2.3" // passes; or strip the leading 'v' before validating
Defensive patterns

Strategy: validation

Validate before calling

const { version } = await (await fetch(`${baseUrl}/health`)).json();
if (!/^\d+\.\d+\.\d+$/.test(version)) throw new Error(`Non-semver OpenCode version: ${version}`);

Type guard

function isPlainSemver(v: unknown): v is string {
  return typeof v === "string" && /^\d+\.\d+\.\d+$/.test(v);
}

Try / catch

try {
  await startDriver();
} catch (e) {
  if (e instanceof Error && e.message.includes("omitted a semantic version")) {
    // curl the health endpoint, inspect raw version, fix binary or proxy
  }
}

Prevention

When it happens

Trigger: 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'.

Common situations: 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.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10). Data as JSON: /api/errors/ce1ccf4ac8560819. Report an issue: GitHub.