multica-ai/multica · error
upload attachment: %w
Error message
upload attachment: %w
What it means
After reading the file locally, the command calls client.UploadChatAttachment to POST it to the server under a 60s timeout. This error wraps any API-side failure: transport errors, non-2xx responses, auth rejection, or server-side upload limits.
Source
Thrown at server/cmd/multica/cmd_attachment.go:91
if taskID == "" {
return fmt.Errorf("no chat task in context: run inside a chat task (MULTICA_TASK_ID set) or pass --task <id>")
}
path := args[0]
if isHTTPURL(path) {
return fmt.Errorf("upload accepts a local file path, not a URL: %s", path)
}
data, err := os.ReadFile(path)
if err != nil {
return fmt.Errorf("read file %s: %w", path, err)
}
ctx, cancel := context.WithTimeout(context.Background(), cli.AtLeastAPITimeout(60*time.Second))
defer cancel()
att, err := client.UploadChatAttachment(ctx, data, path, taskID)
if err != nil {
return fmt.Errorf("upload attachment: %w", err)
}
filename := filepath.Base(path)
// Escape markdown label metacharacters in the filename so a name like
// `report[v2].pdf` does not truncate the snippet's label. Files render as a
// block-level attachment card via `!file[...]( )`; images render inline via
// ``.
label := escapeMarkdownLabel(filename)
markdown := fmt.Sprintf("!file[%s](%s)", label, att.MarkdownURL)
if strings.HasPrefix(att.ContentType, "image/") {
markdown = fmt.Sprintf("", label, att.MarkdownURL)
}
fmt.Fprintln(os.Stderr, "Uploaded:", filename)
return cli.PrintJSON(os.Stdout, map[string]any{
"id": att.ID,
"filename": filename,
"markdown_url": att.MarkdownURL,View on GitHub (pinned to 2c0912b6ec)
Solutions
- Check auth and connectivity first: `multica auth status`
- Confirm the task id is valid and in the current workspace: `multica task list`
- Retry once for transient network errors; check server logs if it persists
- Reduce file size or compress before upload if the server rejects it as too large
- On self-hosted deployments behind nginx/traefik, raise the request body limit
Defensive patterns
Strategy: retry
Try / catch
# bash: distinguish transient from permanent
if ! multica attachment upload "$f" --task "$tid" 2>err.txt; then
grep -qiE 'timeout|connection|reset|EOF' err.txt && retry=1 || retry=0
[ "$retry" = 1 ] && { sleep 3; multica attachment upload "$f" --task "$tid"; } || cat err.txt
fi Prevention
- Run `multica auth status` before scripted upload batches
- Keep files under the server's attachment size limit; compress large binaries first
- Retry once on transient network failures — API uploads are idempotent per call
When it happens
Trigger: Expired or invalid auth token; server unreachable; file exceeds the server's maximum attachment size; task id rejected by the server (deleted task, other workspace); timeout on slow links with large files.
Common situations: Token saved for an old/dead workspace; large binary files (videos, dumps) tripping size limits; self-hosted server behind a proxy with a low client_max_body_size; flaky network from an agent sandbox.
Related errors
AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15).
Data as JSON: /api/errors/5e2bf97dcb6f9eaa.
Report an issue: GitHub.