infiniflow/ragflow · error · Error
Failed to download ${file.path}: ${response.status} ${respon
Error message
Failed to download ${file.path}: ${response.status} ${response.statusText} What it means
Raised when the raw file download (raw.githubusercontent.com or gitee.com/.../raw/...) returns a non-ok HTTP status. Includes the status code and statusText for diagnosis. Common causes: the file was removed between listing and download, the ref moved, the URL requires authentication (private repo), or rate limiting on the raw endpoint.
Source
Thrown at web/src/pages/skills/components/upload-modal.tsx:514
// If download_url is not provided, construct raw URL
if (!downloadUrl) {
if (platform === 'github') {
// https://raw.githubusercontent.com/owner/repo/ref/path
downloadUrl = `${config.rawBase}/${owner}/${repo}/${ref}/${file.path}`;
} else if (platform === 'gitee') {
// https://gitee.com/owner/repo/raw/ref/path
downloadUrl = `${config.rawBase}/${owner}/${repo}/raw/${ref}/${file.path}`;
}
}
if (!downloadUrl) {
throw new Error(`Download URL not available for file: ${file.path}`);
}
const response = await fetch(downloadUrl);
if (!response.ok) {
throw new Error(
`Failed to download ${file.path}: ${response.status} ${response.statusText}`,
);
}
const blob = await response.blob();
const fileName = file.path.split('/').pop() || 'file';
// Use MIME type from extension if blob.type is empty or generic
let fileType = blob.type;
if (
!fileType ||
fileType === 'application/octet-stream' ||
fileType === 'text/plain'
) {
fileType = getMimeTypeFromExtension(file.path);
}
const downloadedFile = new File([blob], fileName, {View on GitHub (pinned to 554fb1133a)
Solutions
- Retry the import — transient 403/429 from raw endpoints often clear
- For private repos, fetch content via the API's download_url (which includes a signed token) or the contents API base64 payload instead of constructing raw URLs
- Verify the file still exists at the given ref in the browser
- Check the status code in the message: 404 = file gone, 403 = auth/rate, 5xx = upstream issue
Example fix
// before
const response = await fetch(downloadUrl);
if (!response.ok) {
throw new Error(`Failed to download ${file.path}: ${response.status} ${response.statusText}`);
}
// after
const response = await fetch(downloadUrl, token ? { headers: { Authorization: `Bearer ${token}` } } : undefined);
if (!response.ok) {
throw new Error(`Failed to download ${file.path}: ${response.status} ${response.statusText}`);
} Defensive patterns
Strategy: retry
Validate before calling
// pre-flight: HEAD the raw URL to confirm it resolves
const probe = await fetch(downloadUrl, { method: 'HEAD' });
if (!probe.ok) {
skipOrWarn(`File unreachable (${probe.status}): ${file.path}`);
} Type guard
function isTransientHttpError(status: number): boolean {
return status === 429 || status >= 500;
} Try / catch
for (let attempt = 0; attempt < 3; attempt++) {
const res = await fetch(downloadUrl);
if (res.ok) { /* use blob */ break; }
if (!isTransientHttpError(res.status)) {
throw new Error(`Failed to download ${file.path}: ${res.status} ${res.statusText}`);
}
await new Promise((r) => setTimeout(r, 2 ** attempt * 500)); // backoff, then retry
} Prevention
- Attach the Authorization header to raw fetches when importing private repos
- Prefer the API's download_url (often signed) over hand-built raw URLs
- Throttle concurrent downloads to avoid raw-endpoint rate limits
When it happens
Trigger: fetch(downloadUrl) for a listed file returns 404 (file deleted/renamed since the listing), 401/403 (private repo, raw URL needs token which is not attached to raw fetches), or 429 rate limit.
Common situations: Repo actively changing during import; private repository imported with a token that authenticates the API but not the raw fetch; large repos hitting raw CDN limits.
Related errors
- Failed to fetch: ${message}
- No files could be downloaded. Errors:\n${downloadErrors.slic
- API rate limit exceeded. ${limit} requests/hour for unauthen
- Repository or path not found. Please check the URL and ensur
- Download URL not available for file: ${file.path}
AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15).
Data as JSON: /api/errors/e7d4d04b2ff42534.
Report an issue: GitHub.