fix(slack): forward resolved botToken to downloadSlackFile

Closes #62088

When `buildActionOpts` returns undefined (default account, no token
override), `downloadSlackFile` calls `resolveToken(undefined, undefined)`
which re-reads raw config via `loadConfig()`. If botToken is a SecretRef
object, `normalizeResolvedSecretInputString` rejects it because it
expects a string — the download silently fails.

This injects the already-resolved botToken from the gateway runtime
snapshot into the download opts as a fallback, bypassing the raw config
re-read. Same root cause as the Discord fix in b51214ec3e.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Martin Garramon
2026-04-06 16:42:49 -03:00
committed by Peter Steinberger
parent d7c3210cd6
commit fd68c28164
2 changed files with 12 additions and 0 deletions

View File

@@ -242,6 +242,16 @@ describe("handleSlackAction", () => {
);
});
it("forwards resolved botToken to action functions instead of relying on config re-read", async () => {
downloadSlackFile.mockResolvedValueOnce(null);
await handleSlackAction(
{ action: "downloadFile", fileId: "F123" },
slackConfig(),
);
const opts = downloadSlackFile.mock.calls[0]?.[1] as { token?: string } | undefined;
expect(opts?.token).toBe("tok");
});
it.each([
{
name: "JSON blocks",

View File

@@ -383,8 +383,10 @@ export async function handleSlackAction(
const maxBytes = account.config?.mediaMaxMb
? account.config.mediaMaxMb * 1024 * 1024
: 20 * 1024 * 1024;
const readToken = getTokenForOperation("read");
const downloaded = await slackActionRuntime.downloadSlackFile(fileId, {
...readOpts,
...(readToken && !readOpts?.token ? { token: readToken } : {}),
maxBytes,
channelId,
threadId: threadId ?? undefined,