{"record":{"id":"8ae0c5c414ffb342","repo":"hcengineering/platform","slug":"unsupported-content-type-contenttype","errorCode":null,"errorMessage":"Unsupported content type: ${contentType}","messagePattern":"Unsupported content type: (.+?)","errorType":"exception","errorClass":"BadRequestError","httpStatus":null,"severity":"warning","filePath":"pods/preview/src/service.ts","lineNumber":147,"sourceCode":"  @withContext('stat-blob')\n  async statBlob (ctx: MeasureContext, workspace: WorkspaceUuid, name: string): Promise<Blob> {\n    const wsId = { uuid: workspace } as any\n\n    const stat = await this.storage.stat(ctx, wsId, name)\n    if (stat !== undefined) {\n      return stat\n    }\n\n    throw new NotFoundError()\n  }\n\n  findProvider (ctx: MeasureContext, contentType: string): PreviewProvider {\n    const provider = this.providers.find((it) => it.supports(contentType))\n    if (provider != null) {\n      return provider\n    }\n\n    throw new BadRequestError(`Unsupported content type: ${contentType}`)\n  }\n\n  private imageKey (workspaceId: string, name: string): string {\n    return `image/${workspaceId}/${name}`\n  }\n\n  private thumbnailKey (workspaceId: string, name: string, params: ThumbnailParams): string {\n    return `thumbnail/${workspaceId}/${name}-${params.width}-${params.height}-${params.format}`\n  }\n}\n","sourceCodeStart":129,"sourceCodeEnd":158,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/pods/preview/src/service.ts#L129-L158","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nconst provider = service.findProvider(ctx, stat.contentType)\n// after\nif (!isSupportedPreviewType(stat.contentType)) {\n  return null // skip preview generation\n}\nconst provider = service.findProvider(ctx, stat.contentType)","handlingStrategy":"validation","validationCode":"const SUPPORTED = ['image/', 'application/pdf', 'application/vnd.openxmlformats', 'application/msword', 'application/vnd.oasis.opendocument', 'video/']\nif (!SUPPORTED.some((p) => stat.contentType.startsWith(p)) && stat.contentType !== 'application/octet-stream') {\n  return null // unsupported preview type; skip\n}","typeGuard":"function hasPreviewProvider(contentType: string): boolean {\n  return ['image/','application/pdf','video/'].some((p) => contentType.startsWith(p)) ||\n    contentType.includes('opendocument') || contentType.includes('openxmlformats') ||\n    contentType === 'application/octet-stream' || contentType === 'application/msword'\n}","tryCatchPattern":"try {\n  return await preview.metadata(ctx, workspace, name)\n} catch (err) {\n  if (/Unsupported content type/.test(err.message)) {\n    ctx.warn('no preview provider', { contentType: stat.contentType })\n    return null\n  }\n  throw err\n}","preventionTips":["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."],"tags":["preview","content-type","bad-request"],"backgroundTag":"unsupported-content-type","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}