From be578b43d39575858a59fa46bfbef1d4e700d6c5 Mon Sep 17 00:00:00 2001 From: bmendonca3 <208517100+bmendonca3@users.noreply.github.com> Date: Thu, 26 Feb 2026 20:09:48 -0700 Subject: [PATCH] secrets: default exec no-output timeout to timeoutMs --- src/secrets/resolve.test.ts | 38 +++++++++++++++++++++++++++++++++++++ src/secrets/resolve.ts | 3 +-- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/secrets/resolve.test.ts b/src/secrets/resolve.test.ts index 64018ca8f7f..68b083013b2 100644 --- a/src/secrets/resolve.test.ts +++ b/src/secrets/resolve.test.ts @@ -178,6 +178,44 @@ describe("secret ref resolver", () => { expect(value).toBe("value:openai/api-key"); }); + it("uses timeoutMs as the default no-output timeout for exec providers", async () => { + if (process.platform === "win32") { + return; + } + const root = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-secrets-resolve-exec-delay-")); + cleanupRoots.push(root); + const scriptPath = path.join(root, "resolver-delay.mjs"); + await writeSecureFile( + scriptPath, + [ + "#!/usr/bin/env node", + "setTimeout(() => {", + " process.stdout.write(JSON.stringify({ protocolVersion: 1, values: { delayed: 'ok' } }));", + "}, 2200);", + ].join("\n"), + 0o700, + ); + + const value = await resolveSecretRefString( + { source: "exec", provider: "execmain", id: "delayed" }, + { + config: { + secrets: { + providers: { + execmain: { + source: "exec", + command: scriptPath, + passEnv: ["PATH"], + timeoutMs: 5000, + }, + }, + }, + }, + }, + ); + expect(value).toBe("ok"); + }); + it("supports non-JSON single-value exec output when jsonOnly is false", async () => { if (process.platform === "win32") { return; diff --git a/src/secrets/resolve.ts b/src/secrets/resolve.ts index 6c34b58a0e3..fc34d48c9a0 100644 --- a/src/secrets/resolve.ts +++ b/src/secrets/resolve.ts @@ -27,7 +27,6 @@ const DEFAULT_MAX_BATCH_BYTES = 256 * 1024; const DEFAULT_FILE_MAX_BYTES = 1024 * 1024; const DEFAULT_FILE_TIMEOUT_MS = 5_000; const DEFAULT_EXEC_TIMEOUT_MS = 5_000; -const DEFAULT_EXEC_NO_OUTPUT_TIMEOUT_MS = 2_000; const DEFAULT_EXEC_MAX_OUTPUT_BYTES = 1024 * 1024; const WINDOWS_ABS_PATH_PATTERN = /^[A-Za-z]:[\\/]/; const WINDOWS_UNC_PATH_PATTERN = /^\\\\[^\\]+\\[^\\]+/; @@ -539,7 +538,7 @@ async function resolveExecRefs(params: { const timeoutMs = normalizePositiveInt(params.providerConfig.timeoutMs, DEFAULT_EXEC_TIMEOUT_MS); const noOutputTimeoutMs = normalizePositiveInt( params.providerConfig.noOutputTimeoutMs, - DEFAULT_EXEC_NO_OUTPUT_TIMEOUT_MS, + timeoutMs, ); const maxOutputBytes = normalizePositiveInt( params.providerConfig.maxOutputBytes,