From 40c5cea4721b363e07ad6a1f502a0986a11ad5da Mon Sep 17 00:00:00 2001 From: Peeyush Aggarwal Date: Thu, 10 Sep 2026 16:32:16 -0700 Subject: [PATCH] fix: skip response body cloning in logResult when debug logging is disabled logResult() unconditionally cloned and read result.response before passing it to logInject(), which itself is a no-op unless OPENCODE_INTERCOM_DEBUG=1. By the time client.session.list(), client.tui.appendPrompt(), etc. return, the SDK has already consumed the underlying response body, so .clone() throws 'TypeError: Body is disturbed or locked' (ERR_BODY_ALREADY_USED). This throw is uncaught at two call sites with concrete user-facing impact: - resolveActiveSessionID(): the exception aborts the function before setActiveSession() runs, so the boot-time session resolution in the top-level connect() IIFE always fails, logging 'Failed to start OpenCode intercom listener' on every plugin start. - injectInbound(): in a TTY session, client.tui.appendPrompt() succeeds (the inbound message text is appended to the prompt input), but the immediately following 'await logResult("inject.append", ...)' throws before the 'if (appended.data === true)' check that guards client.tui.submitPrompt(). The catch block only calls the debug-gated logInject(), so the failure is silent and submitPrompt() is never invoked -- the message sits in the input box requiring a manual Enter instead of being submitted automatically. Guard logResult() the same way logInject() already guards itself, so the unnecessary response clone/read never runs when debug logging is off. Verified: dist rebuilt via 'npm run build', 'npm run typecheck' clean, 'npm test' unaffected (3 pre-existing broker/*.integration.test.ts failures reproduce identically on unpatched main; unrelated to this change). --- dist/index.mjs | 3 +++ dist/plugin.mjs | 3 +++ opencode/plugin.ts | 3 +++ 3 files changed, 9 insertions(+) diff --git a/dist/index.mjs b/dist/index.mjs index 8f4cfc5..4ecc512 100644 --- a/dist/index.mjs +++ b/dist/index.mjs @@ -2511,6 +2511,9 @@ var OpenCodeIntercomPlugin = async ({ client, directory, serverUrl }) => { return { value: error }; } async function logResult(step, result, details = {}) { + if (!debugInject) { + return; + } const responseBody = result.response ? await result.response.clone().text().catch(() => void 0) : void 0; logInject(step, { ...details, diff --git a/dist/plugin.mjs b/dist/plugin.mjs index f3e897e..bf6c2e4 100644 --- a/dist/plugin.mjs +++ b/dist/plugin.mjs @@ -2511,6 +2511,9 @@ var OpenCodeIntercomPlugin = async ({ client, directory, serverUrl }) => { return { value: error }; } async function logResult(step, result, details = {}) { + if (!debugInject) { + return; + } const responseBody = result.response ? await result.response.clone().text().catch(() => void 0) : void 0; logInject(step, { ...details, diff --git a/opencode/plugin.ts b/opencode/plugin.ts index 801f5e0..ce8b373 100644 --- a/opencode/plugin.ts +++ b/opencode/plugin.ts @@ -73,6 +73,9 @@ const OpenCodeIntercomPlugin: Plugin = async ({ client, directory, serverUrl }) error?: unknown; response?: Response; }, details: Record = {}): Promise { + if (!debugInject) { + return; + } const responseBody = result.response ? await result.response.clone().text().catch(() => undefined) : undefined;