hcengineering/platform · warning · BadRequestError
Unsupported content type: ${contentType}
Error message
Unsupported content type: ${contentType} What it means
findProvider scans the registered preview providers (image, doc, pdf, video, octet-stream, fallback) and returns the first whose supports(contentType) matches. If no provider supports the blob's content type, the service throws BadRequestError naming the type. It guards the provider dispatch layer from unknown MIME types.
Source
Thrown at pods/preview/src/service.ts:147
@withContext('stat-blob')
async statBlob (ctx: MeasureContext, workspace: WorkspaceUuid, name: string): Promise<Blob> {
const wsId = { uuid: workspace } as any
const stat = await this.storage.stat(ctx, wsId, name)
if (stat !== undefined) {
return stat
}
throw new NotFoundError()
}
findProvider (ctx: MeasureContext, contentType: string): PreviewProvider {
const provider = this.providers.find((it) => it.supports(contentType))
if (provider != null) {
return provider
}
throw new BadRequestError(`Unsupported content type: ${contentType}`)
}
private imageKey (workspaceId: string, name: string): string {
return `image/${workspaceId}/${name}`
}
private thumbnailKey (workspaceId: string, name: string, params: ThumbnailParams): string {
return `thumbnail/${workspaceId}/${name}-${params.width}-${params.height}-${params.format}`
}
}
View on GitHub (pinned to 63e28dc964)
Solutions
- Log/inspect stat.contentType for the blob and compare against the providers' supports() rules.
- Fix the upload pipeline so a correct Content-Type is stored on the blob.
- Register or enable a provider (e.g. OctetStreamProvider or FallbackProvider) that covers the missing MIME type.
- Convert the file to a supported format (image, PDF, doc, video) before upload.
Example fix
// before
const provider = service.findProvider(ctx, stat.contentType)
// after
if (!isSupportedPreviewType(stat.contentType)) {
return null // skip preview generation
}
const provider = service.findProvider(ctx, stat.contentType) Defensive patterns
Strategy: validation
Validate before calling
const SUPPORTED = ['image/', 'application/pdf', 'application/vnd.openxmlformats', 'application/msword', 'application/vnd.oasis.opendocument', 'video/']
if (!SUPPORTED.some((p) => stat.contentType.startsWith(p)) && stat.contentType !== 'application/octet-stream') {
return null // unsupported preview type; skip
} Type guard
function hasPreviewProvider(contentType: string): boolean {
return ['image/','application/pdf','video/'].some((p) => contentType.startsWith(p)) ||
contentType.includes('opendocument') || contentType.includes('openxmlformats') ||
contentType === 'application/octet-stream' || contentType === 'application/msword'
} Try / catch
try {
return await preview.metadata(ctx, workspace, name)
} catch (err) {
if (/Unsupported content type/.test(err.message)) {
ctx.warn('no preview provider', { contentType: stat.contentType })
return null
}
throw err
} Prevention
- Always send a correct Content-Type on upload.
- Keep OctetStreamProvider/FallbackProvider registered as a catch-all.
- Whitelist previewable MIME types in the client before requesting previews.
- Log offending content types to extend provider coverage.
When it happens
Trigger: Requesting metadata/thumbnail for a blob whose stored contentType matches none of the providers — e.g. an unusual MIME string, empty or misdetected contentType on upload, or a custom provider set that lacks a handler for the type.
Common situations: Uploads stored with wrong/missing contentType (client sent no Content-Type), exotic formats like .heic, .dwg, or application/octet-stream when the OctetStreamProvider is not registered, misconfigured storage recording 'undefined' as contentType.
Related errors
- Unexpected exception: could not detect node path or script p
- Error syncing .npmrc file: ${e}
- platform.status.BadRequest
- platform.status.BadRequest
- Failed to get metadata: ${err.message}
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/8ae0c5c414ffb342.
Report an issue: GitHub.