bytedance/deer-flow · warning
Failed to load upload limits
Error message
Failed to load upload limits
What it means
getUploadLimits GETs /api/threads/{threadId}/uploads/limits and throws on non-ok, with the gateway detail preferred over this fallback text. The response feeds client-side validation of file size/count before uploading.
Source
Thrown at frontend/src/core/uploads/api.ts:85
);
if (!response.ok) {
throw new Error(await readErrorDetail(response, "Upload failed"));
}
return response.json();
}
/**
* Load the upload limits enforced by the gateway for a thread
*/
export async function getUploadLimits(threadId: string): Promise<UploadLimits> {
const response = await fetch(
`${getBackendBaseURL()}/api/threads/${threadId}/uploads/limits`,
);
if (!response.ok) {
throw new Error(
await readErrorDetail(response, "Failed to load upload limits"),
);
}
return response.json();
}
/**
* List all uploaded files for a thread
*/
export async function listUploadedFiles(
threadId: string,
): Promise<ListFilesResponse> {
const response = await fetch(
`${getBackendBaseURL()}/api/threads/${threadId}/uploads/list`,
);
if (!response.ok) {View on GitHub (pinned to 1dd6ba1acb)
Solutions
- Check the status of the /uploads/limits request; 404 usually means uploads are disabled or the thread id is stale.
- 401: refresh auth and let the query retry.
- If uploads are meant to be enabled, verify the gateway config's upload section and route registration.
- On repeated 5xx, inspect gateway logs for the limits handler.
Example fix
// before: unguarded prefetch fails the whole picker
const limits = await getUploadLimits(threadId);
// after: degrade gracefully when limits are unavailable
let limits: UploadLimits | null = null;
try { limits = await getUploadLimits(threadId); }
catch { /* fall back to client-side default limits */ } Defensive patterns
Strategy: fallback
Validate before calling
if (!threadId) { /* skip limits fetch for threads not yet created */ } Type guard
function canQueryLimits(threadId: unknown): threadId is string { return typeof threadId === "string" && threadId.length > 0; } Try / catch
let limits: UploadLimits | null = null;
try { limits = await getUploadLimits(threadId); } catch { limits = null; } // proceed with conservative client defaults Prevention
- Treat limits as an enhancement, not a hard dependency, of the attach flow.
- Cache limits per thread to avoid repeated failing calls.
- Distinguish 404 (uploads disabled) from 401 (auth) in logs.
When it happens
Trigger: Calling the limits endpoint for a thread id the gateway does not know (404), unauthenticated access (401), or the gateway config missing upload settings causing a handler error (500).
Common situations: Opening the attachment picker for a thread created before a server migration; session expired so the limits prefetch fails; uploads feature disabled in gateway config making the route 404/405.
Related errors
- Upload failed
- Failed to list uploaded files
- Failed to delete file
- Failed to prepare ${failedConversions} attachment(s) for upl
- Thread is not ready for file upload.
AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14).
Data as JSON: /api/errors/d8f7e7b2c5aaf41b.
Report an issue: GitHub.