multica-ai/multica · error
Upload failed: ${res.status}
Error message
Upload failed: ${res.status} What it means
Wrap thrown by prepareHermesHome when mountHermesSessionDB fails. When a persistent session store is configured, the overlay's state.db is linked to it so the conversation transcript survives the task; the mount result also reports whether history is actually present so the caller never promises a resume that is not there. Contrary to some comments, this link failing IS fatal here — though a store that is merely absent leaves the database task-local by design.
Source
Thrown at packages/core/api/client.ts:2653
if (opts?.chatSessionId) formData.append("chat_session_id", opts.chatSessionId);
const rid = createRequestId();
const start = Date.now();
this.logger.info("→ POST /api/upload-file", { rid });
const res = await fetch(`${this.baseUrl}/api/upload-file`, {
method: "POST",
headers: this.authHeaders(),
body: formData,
credentials: "include",
signal,
});
if (!res.ok) {
if (res.status === 401) this.handleUnauthorized();
const message = await this.parseErrorMessage(res, `Upload failed: ${res.status}`);
this.logger.error(`← ${res.status} /api/upload-file`, { rid, duration: `${Date.now() - start}ms`, error: message });
throw new Error(message);
}
this.logger.info(`← ${res.status} /api/upload-file`, { rid, duration: `${Date.now() - start}ms` });
const raw = (await res.json()) as unknown;
return parseWithFallback(raw, AttachmentResponseSchema, EMPTY_ATTACHMENT, {
endpoint: "POST /api/upload-file",
});
}
// Chat Sessions
async listChatSessions(
params?: { status?: string },
workspaceSlug?: string,
): Promise<ChatSession[]> {
const query = params?.status ? `?status=${params.status}` : "";
return this.fetch(`/api/chat/sessions${query}`, {
headers: workspaceHeader(workspaceSlug),
});View on GitHub (pinned to 2c0912b6ec)
Solutions
- Verify the session store path exists with the expected type and is writable by the daemon user.
- Remove the conflicting state.db entry inside the per-task hermes-home so a fresh link can be made.
- If the store lives on another filesystem or an unsupported mount, relocate it to the same filesystem as env-root or drop the store config to keep sessions task-local.
- Restore/recreate a corrupted conversation store from backup or reset it.
Defensive patterns
Strategy: validation
Validate before calling
if sessionStore != "" {
fi, err := os.Stat(sessionStore)
if err != nil {
return fmt.Errorf("session store unreachable: %w", err)
}
if err := checkWritable(filepath.Dir(sessionStore)); err != nil {
return fmt.Errorf("session store dir not writable: %w", err)
}
} Try / catch
if err := prepareHermesHome(...); err != nil {
if strings.Contains(err.Error(), "mount conversation sessions") {
// decide: fix the store, or drop sessionStore config to keep sessions task-local (explicit fallback choice)
}
} Prevention
- Health-check conversation store paths before dispatching tasks that promise resume.
- Keep stores on the same filesystem as env-root when links are used.
- Never delete store files while tasks referencing them may run.
When it happens
Trigger: prepareHermesHome is called with a non-empty sessionStore and mountHermesSessionDB(hermesHome, sessionStore, logger) errors — e.g. the store path exists but is not a regular file/dir as expected, linking fails across filesystems or due to permissions, or a conflicting state.db already occupies the target.
Common situations: Session store on a different filesystem than env-root where the link strategy does not apply; store file corrupted or truncated to a non-database; permission drift on the conversation store directory; leftover state.db symlink from an aborted run.
Related errors
- attachment too large for inline preview
- mint PAT: target API URL not set
- mint PAT: response missing token
- daemon profile is not resolved yet; token sync skipped
- API error: ${res.status} ${res.statusText}
AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15).
Data as JSON: /api/errors/d1f866731e3f58fe.
Report an issue: GitHub.