immich-app/immich · error · BadRequestException
Asset does not have valid dimensions
Error message
Asset does not have valid dimensions
What it means
Thrown by PersonService.createFace when the asset has edits but is missing width/height on the asset or exifImageWidth/exifImageHeight on exifInfo. These dimensions are required to scale the client-supplied face box from preview space back to the original image space. BadRequestException -> HTTP 400.
Source
Thrown at server/src/services/person.service.ts:632
const [asset, person] = await Promise.all([
this.assetRepository.getById(dto.assetId, { edits: true, exifInfo: true }),
this.findOrFail(dto.personId),
]);
if (!asset) {
throw new NotFoundException('Asset not found');
}
const edits = asset.edits || [];
let topLeft: Point = { x: dto.x, y: dto.y };
let bottomRight: Point = { x: dto.x + dto.width, y: dto.y + dto.height };
// the coordinates received from the client are based on the edited preview image
// we need to convert them to the coordinate space of the original unedited image
if (edits.length > 0) {
if (!asset.width || !asset.height || !asset.exifInfo?.exifImageWidth || !asset.exifInfo?.exifImageHeight) {
throw new BadRequestException('Asset does not have valid dimensions');
}
// convert from preview to full dimensions
const scaleFactor = asset.width / dto.imageWidth;
topLeft = { x: topLeft.x * scaleFactor, y: topLeft.y * scaleFactor };
bottomRight = { x: bottomRight.x * scaleFactor, y: bottomRight.y * scaleFactor };
const [invertedTopLeft, invertedBottomRight] = transformPoints(
[topLeft, bottomRight],
edits,
{ width: asset.width, height: asset.height },
{ inverse: true },
).points;
// make sure topLeft is top-left and bottomRight is bottom-right
topLeft = {
x: Math.min(invertedTopLeft.x, invertedBottomRight.x),
y: Math.min(invertedTopLeft.y, invertedBottomRight.y),View on GitHub (pinned to 199723261c)
Solutions
- Re-run Metadata Extraction (Administration > Jobs) for the asset so dimensions are populated.
- Tag the face on the unedited version of the asset (no edits => no scaling required).
- If EXIF is irrecoverable, set width/height manually via the metadata API before tagging.
Example fix
// before
if (!asset.width || !asset.height || !asset.exifInfo?.exifImageWidth || !asset.exifInfo?.exifImageHeight) {
throw new BadRequestException('Asset does not have valid dimensions');
}
// after (skip preview->original scaling only when dimensions are missing AND the box matches original space)
const canScale = asset.width && asset.height && asset.exifInfo?.exifImageWidth && asset.exifInfo?.exifImageHeight;
if (edits.length > 0 && !canScale) {
throw new BadRequestException('Cannot map face box: asset dimensions missing. Re-run metadata extraction.');
} Defensive patterns
Strategy: validation
Validate before calling
// Before face-tagging on an edited asset, confirm dimensions exist.
const asset = await assetService.getById(auth, dto.assetId);
if (asset.edits?.length && (!asset.width || !asset.height || !asset.exifInfo?.exifImageWidth || !asset.exifInfo?.exifImageHeight)) {
// queue metadata re-extraction and abort
throw new Error('Asset missing dimensions; queue metadata extraction first');
} Type guard
const hasDimensionsForScale = (a: AssetResponseDto): boolean => !!a.width && !!a.height && !!a.exifInfo?.exifImageWidth && !!a.exifInfo?.exifImageHeight;
Try / catch
try {
await personService.createFace(auth, dto);
} catch (e) {
if (e instanceof BadRequestException && /valid dimensions/i.test(e.message)) {
// trigger metadata re-extraction, then retry once
await jobRepository.queue({ name: JobName.MetadataExtraction, data: { id: dto.assetId } });
}
throw e;
} Prevention
- Run Metadata Extraction before allowing face tagging on edited assets.
- Skip edited assets whose EXIF was stripped.
- Provide width/height via the metadata API if EXIF is irrecoverable.
When it happens
Trigger: POST face-create for an asset that has been edited but whose metadata extraction never produced width/height or EXIF image dimensions (corrupted or stripped EXIF, metadata job that failed).
Common situations: Asset uploaded with stripped EXIF; metadata extraction job failed for that asset; a sidecar-less RAW file with no decoded dimensions; the asset was edited before dimension metadata was populated.
Related errors
- Invalid assetId for feature face or asset is offline
- Asset not found
- May not request original file
- Asset not found or asset is not a video
- Both assets must exist
AI-assisted analysis of immich-app/immich@199723261c (2026-08-12).
Data as JSON: /api/errors/0e6a3433e18d9b55.
Report an issue: GitHub.