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

  1. Verify the URL is still valid and the file exists (open it in a browser or curl -I <url>).
  2. Check permissions/credentials for private storage — generate a fresh presigned URL if it expired.
  3. If the server rejects HEAD (405), fall back to inferring the type from the file extension (contentTypeFromExtension).
  4. 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

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


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/2ea721157296a83a. Report an issue: GitHub.