fix(slack): replace files.uploadV2 with 3-step upload flow to fix missing_scope error#17558
Conversation
Additional Comments (1)
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time! Prompt To Fix With AIThis is a comment left during a code review.
Path: src/slack/send.ts
Line: 199:202
Comment:
**Missing Content-Type header on presigned URL upload**
The `contentType` from `loadWebMedia` is extracted on line 181 (as `_contentType`) but not forwarded to the presigned URL upload. While Slack's presigned URL endpoint generally accepts raw bytes without a `Content-Type` header, setting it explicitly ensures the file's MIME type is correctly recorded server-side — especially for non-obvious file types. Consider passing it through:
```suggestion
const uploadResp = await fetch(uploadUrlResp.upload_url, {
method: "POST",
headers: _contentType ? { "Content-Type": _contentType } : {},
body: new Uint8Array(buffer) as BodyInit,
});
```
<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>
How can I resolve this? If you propose a fix, please make it concise. |
|
@steipete is there anything to fix here? this essentially fixes the file upload in Slack thread. Now the agent would fail to attach the file to the thread (only attaching into the channel and DMs will work without this fix) |
files.uploadV2 from @slack/web-api internally calls the deprecated files.upload endpoint, which fails with missing_scope even when files:write is correctly granted in the bot token scopes. Replace with Slack's recommended 3-step upload flow: 1. files.getUploadURLExternal - get presigned URL + file_id 2. fetch(upload_url) - upload file content 3. files.completeUploadExternal - finalize & share to channel/thread This preserves all existing behavior including thread replies via thread_ts and caption via initial_comment.
30ee226 to
3b80205
Compare
…sing_scope error (openclaw#17558) Cherry-pick of upstream 2a409bb.
…sing_scope error (openclaw#17558) * fix(slack): replace files.uploadV2 with 3-step upload flow files.uploadV2 from @slack/web-api internally calls the deprecated files.upload endpoint, which fails with missing_scope even when files:write is correctly granted in the bot token scopes. Replace with Slack's recommended 3-step upload flow: 1. files.getUploadURLExternal - get presigned URL + file_id 2. fetch(upload_url) - upload file content 3. files.completeUploadExternal - finalize & share to channel/thread This preserves all existing behavior including thread replies via thread_ts and caption via initial_comment. * fix(slack): harden external upload flow and tests --------- Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
…sing_scope error (openclaw#17558) * fix(slack): replace files.uploadV2 with 3-step upload flow files.uploadV2 from @slack/web-api internally calls the deprecated files.upload endpoint, which fails with missing_scope even when files:write is correctly granted in the bot token scopes. Replace with Slack's recommended 3-step upload flow: 1. files.getUploadURLExternal - get presigned URL + file_id 2. fetch(upload_url) - upload file content 3. files.completeUploadExternal - finalize & share to channel/thread This preserves all existing behavior including thread replies via thread_ts and caption via initial_comment. * fix(slack): harden external upload flow and tests --------- Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
…sing_scope error (openclaw#17558) * fix(slack): replace files.uploadV2 with 3-step upload flow files.uploadV2 from @slack/web-api internally calls the deprecated files.upload endpoint, which fails with missing_scope even when files:write is correctly granted in the bot token scopes. Replace with Slack's recommended 3-step upload flow: 1. files.getUploadURLExternal - get presigned URL + file_id 2. fetch(upload_url) - upload file content 3. files.completeUploadExternal - finalize & share to channel/thread This preserves all existing behavior including thread replies via thread_ts and caption via initial_comment. * fix(slack): harden external upload flow and tests --------- Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
…sing_scope error (openclaw#17558) * fix(slack): replace files.uploadV2 with 3-step upload flow files.uploadV2 from @slack/web-api internally calls the deprecated files.upload endpoint, which fails with missing_scope even when files:write is correctly granted in the bot token scopes. Replace with Slack's recommended 3-step upload flow: 1. files.getUploadURLExternal - get presigned URL + file_id 2. fetch(upload_url) - upload file content 3. files.completeUploadExternal - finalize & share to channel/thread This preserves all existing behavior including thread replies via thread_ts and caption via initial_comment. * fix(slack): harden external upload flow and tests --------- Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
…sing_scope error (openclaw#17558) * fix(slack): replace files.uploadV2 with 3-step upload flow files.uploadV2 from @slack/web-api internally calls the deprecated files.upload endpoint, which fails with missing_scope even when files:write is correctly granted in the bot token scopes. Replace with Slack's recommended 3-step upload flow: 1. files.getUploadURLExternal - get presigned URL + file_id 2. fetch(upload_url) - upload file content 3. files.completeUploadExternal - finalize & share to channel/thread This preserves all existing behavior including thread replies via thread_ts and caption via initial_comment. * fix(slack): harden external upload flow and tests --------- Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
…sing_scope error (openclaw#17558) * fix(slack): replace files.uploadV2 with 3-step upload flow files.uploadV2 from @slack/web-api internally calls the deprecated files.upload endpoint, which fails with missing_scope even when files:write is correctly granted in the bot token scopes. Replace with Slack's recommended 3-step upload flow: 1. files.getUploadURLExternal - get presigned URL + file_id 2. fetch(upload_url) - upload file content 3. files.completeUploadExternal - finalize & share to channel/thread This preserves all existing behavior including thread replies via thread_ts and caption via initial_comment. * fix(slack): harden external upload flow and tests --------- Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
…sing_scope error (openclaw#17558) * fix(slack): replace files.uploadV2 with 3-step upload flow files.uploadV2 from @slack/web-api internally calls the deprecated files.upload endpoint, which fails with missing_scope even when files:write is correctly granted in the bot token scopes. Replace with Slack's recommended 3-step upload flow: 1. files.getUploadURLExternal - get presigned URL + file_id 2. fetch(upload_url) - upload file content 3. files.completeUploadExternal - finalize & share to channel/thread This preserves all existing behavior including thread replies via thread_ts and caption via initial_comment. * fix(slack): harden external upload flow and tests --------- Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
… fix missing_scope error (openclaw#17558)" This reverts commit 6951d92.
…sing_scope error (openclaw#17558) * fix(slack): replace files.uploadV2 with 3-step upload flow files.uploadV2 from @slack/web-api internally calls the deprecated files.upload endpoint, which fails with missing_scope even when files:write is correctly granted in the bot token scopes. Replace with Slack's recommended 3-step upload flow: 1. files.getUploadURLExternal - get presigned URL + file_id 2. fetch(upload_url) - upload file content 3. files.completeUploadExternal - finalize & share to channel/thread This preserves all existing behavior including thread replies via thread_ts and caption via initial_comment. * fix(slack): harden external upload flow and tests --------- Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
…sing_scope error (openclaw#17558) * fix(slack): replace files.uploadV2 with 3-step upload flow files.uploadV2 from @slack/web-api internally calls the deprecated files.upload endpoint, which fails with missing_scope even when files:write is correctly granted in the bot token scopes. Replace with Slack's recommended 3-step upload flow: 1. files.getUploadURLExternal - get presigned URL + file_id 2. fetch(upload_url) - upload file content 3. files.completeUploadExternal - finalize & share to channel/thread This preserves all existing behavior including thread replies via thread_ts and caption via initial_comment. * fix(slack): harden external upload flow and tests --------- Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
…sing_scope error (openclaw#17558) * fix(slack): replace files.uploadV2 with 3-step upload flow files.uploadV2 from @slack/web-api internally calls the deprecated files.upload endpoint, which fails with missing_scope even when files:write is correctly granted in the bot token scopes. Replace with Slack's recommended 3-step upload flow: 1. files.getUploadURLExternal - get presigned URL + file_id 2. fetch(upload_url) - upload file content 3. files.completeUploadExternal - finalize & share to channel/thread This preserves all existing behavior including thread replies via thread_ts and caption via initial_comment. * fix(slack): harden external upload flow and tests --------- Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
…sing_scope error (openclaw#17558) * fix(slack): replace files.uploadV2 with 3-step upload flow files.uploadV2 from @slack/web-api internally calls the deprecated files.upload endpoint, which fails with missing_scope even when files:write is correctly granted in the bot token scopes. Replace with Slack's recommended 3-step upload flow: 1. files.getUploadURLExternal - get presigned URL + file_id 2. fetch(upload_url) - upload file content 3. files.completeUploadExternal - finalize & share to channel/thread This preserves all existing behavior including thread replies via thread_ts and caption via initial_comment. * fix(slack): harden external upload flow and tests --------- Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
…sing_scope error (openclaw#17558) Cherry-pick of upstream 2a409bb.
Problem
uploadSlackFile()usesclient.files.uploadV2()from@slack/web-api, which internally calls the deprecatedfiles.uploadendpoint. This fails withmissing_scopeeven whenfiles:writeis correctly granted in the bot token scopes.The direct REST API (
files.getUploadURLExternal→ upload →files.completeUploadExternal) works fine with the same token, confirming the scope is present but the SDK method uses a different code path.Fix
Replace the single
files.uploadV2()call with Slack's recommended 3-step upload flow:files.getUploadURLExternal— get presigned upload URL + file_idfetch(upload_url)— upload file content to presigned URLfiles.completeUploadExternal— finalize & share to channel/threadChanges
src/slack/send.tsuploadSlackFile()function body is modifiedthread_ts, captions viainitial_comment)FilesUploadV2Argumentstype importTesting
Manually verified the 3-step flow works correctly:
thread_ts)files:writescope — no moremissing_scopeerrorGreptile Summary
This PR replaces the broken
files.uploadV2()SDK call inuploadSlackFile()with Slack's recommended 3-step upload flow:getUploadURLExternal→ presigned URL POST →completeUploadExternal. The change fixesmissing_scopeerrors that occurred becausefiles.uploadV2internally uses the deprecatedfiles.uploadendpoint.thread_ts, captions viainitial_comment) are preservedmessageIdinSlackSendResultwon't be a valid Slacktsfor file-only uploads (affecting downstream operations like reactions/edits), but this PR does not change that behaviorFilesUploadV2Argumentsimport is correctly removedConfidence Score: 4/5
uploadSlackFilefunction body insrc/slack/send.ts.Last reviewed commit: 30ee226