{"record":{"id":"0e6a3433e18d9b55","repo":"immich-app/immich","slug":"asset-does-not-have-valid-dimensions","errorCode":null,"errorMessage":"Asset does not have valid dimensions","messagePattern":"Asset does not have valid dimensions","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"server/src/services/person.service.ts","lineNumber":701,"sourceCode":"    const [asset, person] = await Promise.all([\n      this.assetRepository.getById(dto.assetId, { edits: true, exifInfo: true }),\n      this.findOrFail(auth, dto.personId),\n    ]);\n\n    if (!asset) {\n      throw new NotFoundException('Asset not found');\n    }\n\n    const edits = asset.edits || [];\n\n    let topLeft: Point = { x: dto.x, y: dto.y };\n    let bottomRight: Point = { x: dto.x + dto.width, y: dto.y + dto.height };\n\n    // the coordinates received from the client are based on the edited preview image\n    // we need to convert them to the coordinate space of the original unedited image\n    if (edits.length > 0) {\n      if (!asset.width || !asset.height || !asset.exifInfo?.exifImageWidth || !asset.exifInfo?.exifImageHeight) {\n        throw new BadRequestException('Asset does not have valid dimensions');\n      }\n\n      // convert from preview to full dimensions\n      const scaleFactor = asset.width / dto.imageWidth;\n      topLeft = { x: topLeft.x * scaleFactor, y: topLeft.y * scaleFactor };\n      bottomRight = { x: bottomRight.x * scaleFactor, y: bottomRight.y * scaleFactor };\n\n      const [invertedTopLeft, invertedBottomRight] = transformPoints(\n        [topLeft, bottomRight],\n        edits,\n        { width: asset.width, height: asset.height },\n        { inverse: true },\n      ).points;\n\n      // make sure topLeft is top-left and bottomRight is bottom-right\n      topLeft = {\n        x: Math.min(invertedTopLeft.x, invertedBottomRight.x),\n        y: Math.min(invertedTopLeft.y, invertedBottomRight.y),","sourceCodeStart":683,"sourceCodeEnd":719,"githubUrl":"https://github.com/immich-app/immich/blob/f48d4b332127ad365ba256108799ca8f571d2dd5/server/src/services/person.service.ts#L683-L719","documentation":"When the target asset has edits (crops/rotations from the edit stack), the service must convert client coordinates from the edited preview space to the original image space. That conversion requires asset.width/height and exifInfo.exifImageWidth/exifImageHeight; if any is missing or zero, it throws BadRequestException('Asset does not have valid dimensions') instead of computing a bogus region.","triggerScenarios":"Updating a face region on an asset that has edits but lacks valid width/height metadata or EXIF image dimensions (missing EXIF, dimension-less sidecar, corrupted metadata, or media not yet fully processed).","commonSituations":"Screenshots or images stripped of EXIF that were then edited, assets mid-ingestion where dimensions aren't computed yet, corrupted metadata after restore, or third-party uploads without dimensions.","solutions":["Remove the asset's edits (revert to original) before updating the face region, so no coordinate conversion is needed.","Re-upload or re-process the asset so width/height and EXIF dimensions are populated (run metadata extraction job).","Verify the file's EXIF; inject missing dimensions via exiftool if the source lacks them.","Retry after the asset finishes processing (check asset.status is ready and exifInfo present)."],"exampleFix":"// before\nawait updateFaceRegion({ assetId, x, y, width, height, imageWidth }); // asset has edits but no EXIF dims\n// after\nawait api.assetsApi.replaceAsset({ id: assetId, ... }); // or revert edits first\nawait updateFaceRegion({ assetId, x, y, width, height, imageWidth });","handlingStrategy":"fallback","validationCode":"const asset = await api.assetsApi.getAssetInfo({ id: assetId });\nconst hasEdits = (asset.edits?.length ?? 0) > 0;\nconst dimsOk = !hasEdits || (asset.exifInfo?.exifImageWidth && asset.exifInfo?.exifImageHeight);\nif (!dimsOk) throw new Error('Asset lacks EXIF dimensions required for edited-coordinate conversion');","typeGuard":"function hasValidDimensions(asset) {\n  return Boolean(asset.width && asset.height && asset.exifInfo?.exifImageWidth && asset.exifInfo?.exifImageHeight);\n}","tryCatchPattern":"try {\n  await updateFaceRegion(dto);\n} catch (e) {\n  if (e.status === 400 && String(e.message).includes('valid dimensions')) {\n    // fall back to reverting edits or re-running the metadata extraction job\n  } else throw e;\n}","preventionTips":["Ensure metadata extraction completes before editing faces on edited assets.","Avoid stripping EXIF from uploads; inject dimensions if missing.","Prefer reverting edits on the asset before sending preview coordinates."],"tags":["dimensions","exif","face","metadata","bad-request"],"backgroundTag":"missing-required-config-field","analyzedSha":"f48d4b332127ad365ba256108799ca8f571d2dd5","analyzedAt":"2026-09-15T07:20:19.675Z","contentChangedAt":"2026-09-15T07:20:19.675Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}