relay message file upload cannot succeed. The file is never uploaded — the CLI serialises the local path into the attachments array and the server rejects it.
Reproduce
relay agent register upload-probe # capture the token
RELAY_AGENT_TOKEN=$TOK relay channel create probe-ch
printf 'hello\n' > /tmp/probe.txt
RELAY_AGENT_TOKEN=$TOK relay message file upload /tmp/probe.txt --channel probe-ch --text 'x'
# Invalid attachments: file ids must exist in workspace and be complete
Verified against production cloud with a clean fixture, a fresh agent and a fresh channel.
Root cause
packages/cli/src/cli/commands/message.ts sends:
attachments: [{ type: 'file', path: filePath }]
serializeAttachmentInputs (packages/sdk/src/messaging/relaycast-translate.ts:301) is just:
typeof attachment === 'string' ? attachment : JSON.stringify(attachment)
so the literal string {"type":"file","path":"/tmp/probe.txt"} is sent where the API expects a file id. Nothing ever reads the file or uploads bytes.
What the API actually requires
@relaycast/types file.d.ts defines a three-step presigned upload:
POST UploadRequest { filename, content_type, size_bytes } → UploadResponse { id, upload_url, expires_at }
PUT the bytes to upload_url
- Send the message with
attachments: [file_id]; the record must reach status: "complete"
@relaycast/sdk exposes no files API (relay.d.ts has no files/upload member), so this needs SDK support before the CLI can be fixed.
Secondary bug
--help documents --text as defaulting to "", but the API rejects empty text with text is required — so the documented default can never work. Either make --text required or default it to the filename.
Impact
message-file-upload is verify_tier: 3 in the feature manifest — presented as a supported feature that cannot work at all.
Found by workflows/verify-features.ts during a live end-to-end run.
relay message file uploadcannot succeed. The file is never uploaded — the CLI serialises the local path into the attachments array and the server rejects it.Reproduce
Verified against production cloud with a clean fixture, a fresh agent and a fresh channel.
Root cause
packages/cli/src/cli/commands/message.tssends:serializeAttachmentInputs(packages/sdk/src/messaging/relaycast-translate.ts:301) is just:so the literal string
{"type":"file","path":"/tmp/probe.txt"}is sent where the API expects a file id. Nothing ever reads the file or uploads bytes.What the API actually requires
@relaycast/typesfile.d.tsdefines a three-step presigned upload:POSTUploadRequest { filename, content_type, size_bytes }→UploadResponse { id, upload_url, expires_at }PUTthe bytes toupload_urlattachments: [file_id]; the record must reachstatus: "complete"@relaycast/sdkexposes no files API (relay.d.tshas no files/upload member), so this needs SDK support before the CLI can be fixed.Secondary bug
--helpdocuments--textas defaulting to"", but the API rejects empty text withtext is required— so the documented default can never work. Either make--textrequired or default it to the filename.Impact
message-file-uploadisverify_tier: 3in the feature manifest — presented as a supported feature that cannot work at all.Found by
workflows/verify-features.tsduring a live end-to-end run.