diff --git a/packages/opencode/src/global/index.ts b/packages/opencode/src/global/index.ts index 10b6125a6a9..f6020240bb6 100644 --- a/packages/opencode/src/global/index.ts +++ b/packages/opencode/src/global/index.ts @@ -50,6 +50,9 @@ if (version !== CACHE_VERSION) { }), ), ) - } catch (e) {} - await Bun.file(path.join(Global.Path.cache, "version")).write(CACHE_VERSION) + await Bun.file(path.join(Global.Path.cache, "version")).write(CACHE_VERSION) + } catch (e) { + // Log to stderr since Log module may not be initialized yet (circular dependency) + console.error("[global] failed to clear cache:", e instanceof Error ? e.message : String(e)) + } } diff --git a/packages/opencode/src/mcp/index.ts b/packages/opencode/src/mcp/index.ts index 29e958fe357..df01a4aaad2 100644 --- a/packages/opencode/src/mcp/index.ts +++ b/packages/opencode/src/mcp/index.ts @@ -812,11 +812,11 @@ export namespace MCP { await new Promise((resolve, reject) => { // Give the process a moment to fail if it's going to const timeout = setTimeout(() => resolve(), 500) - subprocess.on("error", (error) => { + subprocess.once("error", (error) => { clearTimeout(timeout) reject(error) }) - subprocess.on("exit", (code) => { + subprocess.once("exit", (code) => { if (code !== null && code !== 0) { clearTimeout(timeout) reject(new Error(`Browser open failed with exit code ${code}`)) diff --git a/packages/opencode/src/session/retry.ts b/packages/opencode/src/session/retry.ts index a71a6a38241..e643759078e 100644 --- a/packages/opencode/src/session/retry.ts +++ b/packages/opencode/src/session/retry.ts @@ -89,7 +89,7 @@ export namespace SessionRetry { if (json.type === "error" && json.error?.code?.includes("rate_limit")) { return "Rate Limited" } - return JSON.stringify(json) + return undefined } catch { return undefined } diff --git a/packages/opencode/src/util/timeout.ts b/packages/opencode/src/util/timeout.ts index 8779965521c..3f2167f3550 100644 --- a/packages/opencode/src/util/timeout.ts +++ b/packages/opencode/src/util/timeout.ts @@ -1,10 +1,7 @@ export function withTimeout(promise: Promise, ms: number): Promise { let timeout: NodeJS.Timeout return Promise.race([ - promise.then((result) => { - clearTimeout(timeout) - return result - }), + promise.finally(() => clearTimeout(timeout)), new Promise((_, reject) => { timeout = setTimeout(() => { reject(new Error(`Operation timed out after ${ms}ms`)) diff --git a/packages/opencode/test/session/retry.test.ts b/packages/opencode/test/session/retry.test.ts index a483a015271..da74e264eb3 100644 --- a/packages/opencode/test/session/retry.test.ts +++ b/packages/opencode/test/session/retry.test.ts @@ -97,9 +97,9 @@ describe("session.retry.retryable", () => { expect(SessionRetry.retryable(error)).toBe("Provider is overloaded") }) - test("handles json messages without code", () => { + test("returns undefined for json messages without known retryable patterns", () => { const error = wrap(JSON.stringify({ error: { message: "no_kv_space" } })) - expect(SessionRetry.retryable(error)).toBe(`{"error":{"message":"no_kv_space"}}`) + expect(SessionRetry.retryable(error)).toBeUndefined() }) test("does not throw on numeric error codes", () => {