{"record":{"id":"af99dc5a0ea2695a","repo":"immich-app/immich","slug":"unexpected-path-type","errorCode":null,"errorMessage":"Unexpected path type:","messagePattern":"Unexpected path type:","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"server/src/cores/storage.core.ts","lineNumber":350,"sourceCode":"      case AssetFileType.EncodedVideo:\n      case AssetFileType.Thumbnail:\n      case AssetFileType.Preview:\n      case AssetFileType.Sidecar:\n      case AssetPathType.EncodedVideo: {\n        return this.assetRepository.upsertFile({ assetId: id, type: pathType as AssetFileType, path: newPath });\n      }\n\n      case PersonPathType.Face: {\n        if (!ownerId) {\n          this.logger.warn('Unable to save person path without an owner');\n          return;\n        }\n\n        return this.personRepository.update({ ownerId, personGroupId: id, thumbnailPath: newPath });\n      }\n\n      case UserPathType.Profile: {\n        this.logger.warn('Unexpected path type:', pathType);\n        return;\n      }\n    }\n  }\n\n  static getNestedFolder(folder: StorageFolder, ownerId: string, filename: string): string {\n    return join(StorageCore.getFolderLocation(folder, ownerId), filename.slice(0, 2), filename.slice(2, 4));\n  }\n\n  static getNestedPath(folder: StorageFolder, ownerId: string, filename: string): string {\n    return join(StorageCore.getNestedFolder(folder, ownerId, filename), filename);\n  }\n\n  private async getDevices() {\n    try {\n      return await this.storageRepository.readdir('/dev/dri');\n    } catch {\n      this.logger.debug('No devices found in /dev/dri.');","sourceCodeStart":332,"sourceCodeEnd":368,"githubUrl":"https://github.com/immich-app/immich/blob/e55ac299a4ec7cb372e35dbf2c6c05ee9ce77f6c/server/src/cores/storage.core.ts#L332-L368","documentation":"savePath's switch has no matching case for the given path type (only UserPathType.Profile is shown warning here); the function logs 'Unexpected path type:' with the value and returns without saving. In practice this means the new path was moved on disk but never persisted in the database.","triggerScenarios":"moveFile -> savePath receives a pathType not handled by the switch — e.g. an enum value added later or a type passed incorrectly — landing in a fall-through case that logs the warning.","commonSituations":"Upgrading Immich and running a migration that passes a new AssetPathType/PersonPathType value the running savePath does not know; calling moveFile with AssetPathType vs PersonPathType confusion; developer-added enum member without a case.","solutions":["Add a case for the new path type in savePath's switch","Verify which pathType value is being logged and pass the correct enum","Update code after enum changes instead of reusing stale call sites","Fail loudly instead of warn-return when the path type is unknown"],"exampleFix":"// before\ncase UserPathType.Profile:\n  this.logger.warn('Unexpected path type:', pathType);\n  return;\n// after\ndefault:\n  throw new Error(`Unexpected path type: ${pathType}`);","handlingStrategy":"validation","validationCode":"const handled = [AssetPathType.Original, AssetPathType.JPEG, AssetPathType.Preview, AssetPathType.EncodedVideo, PersonPathType.Face, UserPathType.Profile];\nif (!handled.includes(pathType)) throw new Error(`Unhandled path type: ${pathType}`);","typeGuard":"function isKnownPathType(v: string): v is AssetPathType | PersonPathType | UserPathType { return handled.includes(v as never); }","tryCatchPattern":"try {\n  await moveFile(pathType, id, newPath);\n} catch (e) {\n  if (String(e).includes('Unexpected path type')) revertFilesystemMove(newPath, oldPath);\n  throw e;\n}","preventionTips":["Make the switch exhaustive with a default that throws","Run a compiler check (TS exhaustive switch) after enum changes","Add tests covering every path-type enum value","Never warn-and-return after the file was already moved on disk"],"tags":["enum","unhandled-case","database","immich"],"backgroundTag":"unsupported-enum-value","analyzedSha":"e55ac299a4ec7cb372e35dbf2c6c05ee9ce77f6c","analyzedAt":"2026-09-15T07:20:19.675Z","contentChangedAt":"2026-09-15T07:20:19.675Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}