makeplane/plane · warning · Error
Invalid file type. Please select an image.
Error message
Invalid file type. Please select an image.
What it means
Thrown by the cover-image upload helper after a local image URL is fetched. The code reads the response blob and checks that its MIME type starts with 'image/'; anything else (HTML error pages, octet-stream, PDFs) is rejected before being wrapped into a File and uploaded via fileService. The post-fetch check exists because URL extensions and filenames are unreliable signals of real content type.
Source
Thrown at apps/web/helpers/cover-image.helper.ts:221
entityIdentifier: string;
entityType: EFileAssetType;
isUserAsset?: boolean;
}
): Promise<string> => {
const { workspaceSlug, entityIdentifier, entityType, isUserAsset = false } = uploadConfig;
// Fetch the local image
const response = await fetch(imageUrl);
if (!response.ok) {
throw new Error(`Failed to fetch image: ${response.statusText}`);
}
const blob = await response.blob();
// Validate it's actually an image
if (!blob.type.startsWith("image/")) {
throw new Error("Invalid file type. Please select an image.");
}
const fileName = imageUrl.split("/").pop()?.split("?")[0] || "image.jpg";
const file = new File([blob], fileName, { type: blob.type });
// Upload based on context
if (isUserAsset) {
const uploadResult = await fileService.uploadUserAsset(
{
entity_identifier: entityIdentifier,
entity_type: entityType,
},
file
);
return uploadResult.asset_url;
} else {
if (!workspaceSlug) {
throw new Error("Workspace slug is required for workspace asset upload");View on GitHub (pinned to 1c8a60f858)
Solutions
- Open the URL directly in a browser or run `curl -I <url>` and confirm the Content-Type header is image/*.
- If the server returns application/octet-stream for real images, fix the upstream/CDN to send the correct image MIME.
- Add a HEAD preflight before calling the helper and show a user-facing error if Content-Type is not image/*.
- For SVGs, ensure the source emits image/svg+xml; if support is unwanted, block it explicitly upstream.
Example fix
// before
await uploadCoverImageHelper(imageUrl, ...);
// after
const probe = await fetch(imageUrl, { method: 'HEAD' });
const ct = probe.headers.get('content-type') ?? '';
if (!ct.startsWith('image/')) {
throw new Error(`URL is not an image (got ${ct})`);
}
await uploadCoverImageHelper(imageUrl, ...); Defensive patterns
Strategy: validation
Validate before calling
async function isImageUrl(url: string): Promise<boolean> {
const probe = await fetch(url, { method: 'HEAD' });
const ct = probe.headers.get('content-type') ?? '';
return probe.ok && ct.startsWith('image/');
} Type guard
function isImageBlob(blob: Blob): boolean {
return typeof blob.type === 'string' && blob.type.startsWith('image/');
} Try / catch
try {
await uploadCoverImageHelper(url, ctx);
} catch (e) {
if (e instanceof Error && e.message.startsWith('Invalid file type')) {
notifyUser('That URL is not an image. Pick an image file.');
} else throw e;
} Prevention
- Pre-validate with a HEAD request
- Constrain the file picker to image/* accept attribute
- Reject non-image Content-Types at the upload proxy
When it happens
Trigger: Calling the cover-image helper with a URL whose response 'Content-Type' is not an image MIME (e.g. text/html for an SPA route or error page, application/octet-stream from a misconfigured CDN, application/pdf). Also when the blob decodes without a recognized type (blob.type === '').
Common situations: Passing a frontend route or 404 HTML page instead of the raw asset URL; CDN/proxy stripping Content-Type or serving binary/octet-stream; file still transcoding on the server so the link returns JSON metadata; cross-origin response where the gateway rewrites the type.
Related errors
- File too large. Size should not exceed 5 MB.
- File too large. Size should not exceed 5 MB.
- Missing required fields.
- Failed to fetch image: ${response.statusText}
- Invalid expression: empty or null data
AI-assisted analysis of makeplane/plane@1c8a60f858 (2026-08-12).
Data as JSON: /api/errors/8b1761fc92e999f6.
Report an issue: GitHub.