Skip to content

Slack: reject login HTML from private file fetch (missing files:read) #1317

Description

@cursor

Suggestion for Eve: fail loudly when Slack private file fetch returns login HTML

Context

Family Eve agent (Tjalfe) on Vercel Connect Slack. Users uploaded images in Slack; the model replied that it received a Slack login page instead of the photo.

Root cause (ops)

The Connect Slack connector was missing bot scope files:read. Chat scopes worked; private file download did not.

Root cause (framework UX)

Eve's createSlackFetchFile in packages/eve/src/public/channels/slack/attachments.ts does:

const response = await fetch(url, {
  headers: { authorization: `Bearer ${token}` },
});
if (!response.ok) throw new Error(...);
return { bytes: Buffer.from(await response.arrayBuffer()), mediaType: ... };

When the bot token lacks files:read (or otherwise cannot read the file), Slack often returns HTTP 200 + browser login HTML, not a 401/403. Eve treats that as success and stages the HTML as the attachment. The model then honestly reports a Slack sign-in page — which looks like a vision/auth mystery rather than a missing scope.

Suggested change

In createSlackFetchFile (and tests in attachments.test.ts):

  1. After a successful fetch, if Content-Type is text/html or the body looks like <!DOCTYPE html / <html, throw instead of returning bytes.
  2. Error message should mention: missing/insufficient Slack bot scope (typically files:read), and that Connect/Slack apps need reinstall after adding scopes.
  3. Optionally document files:read in the Slack channel docs under Attachments (create-time Advanced scopes for Connect).

Why this belongs in Eve

Stock fetch + Bearer is fine for the happy path once files:read is present. The gap is silent failure mode: login HTML reaches the model instead of a clear framework error. Other Slack clients (e.g. OpenClaw) already reject HTML login payloads for this reason.

Repro shape

  1. Slack connector without files:read
  2. User uploads an image and @mentions the agent
  3. Observe staged attachment / model output describing a Slack login page
  4. Add files:read, reinstall workspace → same flow works

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions