different-ai/openwork · error

Unknown error

Error message

Unknown error

What it means

unwrap converts an error carried on an opencode client result (Error, string, or any JSON value) into a thrown Error, falling back to "Unknown error" when the message is empty. It backs unwrapSessionResult, aborted, revertSession, forkSession, unrevertSession and setSessionArchived — any of these calls can surface it.

Source

Thrown at apps/app/src/app/lib/opencode.ts:269

        ...init,
        headers,
      },
      timeoutMs,
    );
  };
};

export function unwrap<T>(result: FieldsResult<T>): NonNullable<T> {
  if (result.data !== undefined) {
    return result.data as NonNullable<T>;
  }
  const message =
    result.error instanceof Error
      ? result.error.message
      : typeof result.error === "string"
        ? result.error
        : JSON.stringify(result.error);
  throw new Error(message || "Unknown error");
}

export function createClient(baseUrl: string, directory?: string, auth?: OpencodeAuth) {
  const headers: Record<string, string> = {};
  if (!isDesktopRuntime()) {
    const authHeader = resolveAuthHeader(auth);
    if (authHeader) {
      headers.Authorization = authHeader;
    }
  }

  const fetchImpl = isDesktopRuntime()
    ? createDesktopFetch(auth)
    : (input: RequestInfo | URL, init?: RequestInit) => {
        const timeoutMs = requestIsStreaming(input, init) ? 0 : DEFAULT_OPENCODE_REQUEST_TIMEOUT_MS;
        return fetchWithTimeout(globalThis.fetch, input, init, timeoutMs);
      };
  const client = createOpencodeClient({

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Capture the raw result object at the call site to recover the real failure cause.
  2. Check opencode server logs for the failing session operation (session id, route, status).
  3. Align the opencode client SDK and server versions so error payloads match the expected shape.

Example fix

// before
throw new Error(message || "Unknown error");
// after: preserve the raw payload
throw new Error(message || `Unknown error: ${JSON.stringify(result.error ?? null)}`);
Defensive patterns

Strategy: try-catch

Validate before calling

if (result && typeof result === "object" && "error" in result) {
  console.debug("unwrap candidate error:", result.error); // preserve payload before it is normalized away
}

Try / catch

try {
  await forkSession(sessionId);
} catch (err) {
  if (err instanceof Error && err.message === "Unknown error") {
    // detail lost in unwrap; verify session existence server-side
    const s = await getClient().session.get(sessionId);
    if (!s) throw new Error(`Session ${sessionId} not found (original error was empty).`);
    throw err;
  }
  throw err;
}

Prevention

When it happens

Trigger: An opencode client session operation returns `{ error: ... }` whose normalized message is empty: empty-string error, object that stringifies to empty, or an error field set without detail by the server/SDK.

Common situations: Session already deleted when calling revert/fork, server returning bare `{error:true}`-style bodies, SDK version mismatch between client expectations and server responses.

Related errors


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/ce1441dd66ba75a2. Report an issue: GitHub.