mastra-ai/mastra · error
Failed to get file content type
Error message
Failed to get file content type
What it means
getFileContentType performs a HEAD request against a URL and uses the response's content-type header as the file's content type. This error is thrown when the HEAD request completes but returns a non-2xx status, meaning the server responded but did not serve the file, so no trustworthy content type is available.
Source
Thrown at packages/playground-ui/src/lib/file/contentTypeFromUrl.ts:34
return EXTENSION_TO_MIME[extension.toLowerCase()];
}
};
export const getFileContentType = async (url: string) => {
// Cloud-storage URIs are fetched server-side by the model provider (e.g. Vertex
// AI for `gs://`, Bedrock for `s3://`); the browser cannot HEAD them, so infer
// the content type from the extension directly.
if (NON_FETCHABLE_REMOTE_SCHEMES.some(scheme => url.startsWith(scheme))) {
return contentTypeFromExtension(url);
}
try {
const response = await fetch(url, {
method: 'HEAD',
});
if (!response.ok) {
throw new Error('Failed to get file content type');
}
const contentType = response.headers.get('content-type');
if (!contentType) {
throw new Error('Failed to get file content type');
}
return contentType;
} catch {
// fetch failed — try to infer content type from the file extension
return contentTypeFromExtension(url);
}
};
View on GitHub (pinned to 75dd419e61)
Solutions
- Verify the URL is still valid and the file exists (open it in a browser or curl -I <url>).
- Check permissions/credentials for private storage — generate a fresh presigned URL if it expired.
- If the server rejects HEAD (405), fall back to inferring the type from the file extension (contentTypeFromExtension).
- Wrap the call and rely on the built-in catch path: a fetch failure falls back to extension-based inference, but an HTTP error status surfaces here — handle it explicitly.
Defensive patterns
Strategy: fallback
Validate before calling
const ok = await fetch(url, { method: 'HEAD' }).then(r => r.ok).catch(() => false);
if (!ok) console.warn(`HEAD failed for ${url}; will need extension fallback`); Try / catch
let contentType: string;
try {
contentType = await getFileContentType(url);
} catch {
contentType = contentTypeFromExtension(url) ?? 'application/octet-stream';
} Prevention
- Check file availability (curl -I) when URLs come from expiring presigned storage links.
- Verify the storage/CDN allows HEAD requests (some return 405).
- Regenerate presigned URLs before use rather than caching them past expiry.
When it happens
Trigger: Calling getFileContentType(url) where fetch(url, { method: 'HEAD' }) resolves with response.ok === false — e.g. the file URL returns 404 (file deleted), 403 (no permission), or the storage endpoint rejects HEAD requests with 405.
Common situations: Files uploaded to storage that were later removed or expired (presigned URL expired), private buckets where the caller lacks read access, or servers/s CDNs that do not allow the HEAD method.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- Failed to load repository settings (${res.status})
- Failed to delete session (${res.status})
- Failed to rename session (${res.status})
- Agent Learning request failed (${response.status})
- Slack OAuth HTTP error: ${tokenResponse.status} ${tokenRespo
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/2ea721157296a83a.
Report an issue: GitHub.