{"record":{"id":"abef5c45b7da2619","repo":"immich-app/immich","slug":"target-media-location-must-be-an-absolute-path","errorCode":null,"errorMessage":"Target media location must be an absolute path","messagePattern":"Target media location must be an absolute path","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/src/services/cli.service.ts","lineNumber":218,"sourceCode":"  }\n\n  async migrateFilePaths({\n    oldValue,\n    newValue,\n    confirm,\n  }: {\n    oldValue: string;\n    newValue: string;\n    confirm: (data: { sourceFolder: string; targetFolder: string }) => Promise<boolean>;\n  }): Promise<boolean> {\n    let sourceFolder = oldValue;\n    if (sourceFolder.startsWith('./')) {\n      sourceFolder = sourceFolder.slice(2);\n    }\n\n    const targetFolder = newValue;\n    if (!isAbsolute(targetFolder)) {\n      throw new Error('Target media location must be an absolute path');\n    }\n\n    if (!(await confirm({ sourceFolder, targetFolder }))) {\n      return false;\n    }\n\n    await this.databaseRepository.migrateFilePaths(sourceFolder, targetFolder);\n\n    return true;\n  }\n\n  cleanup() {\n    return this.databaseRepository.shutdown();\n  }\n}\n","sourceCodeStart":200,"sourceCodeEnd":234,"githubUrl":"https://github.com/immich-app/immich/blob/e55ac299a4ec7cb372e35dbf2c6c05ee9ce77f6c/server/src/services/cli.service.ts#L200-L234","documentation":"During a media-location migration, `migrateFilePaths` validates that the new target folder is an absolute path using isAbsolute(). Relative paths like './photos' or 'photos' are rejected with this Error because the migration must rewrite external-library asset paths to unambiguous locations.","triggerScenarios":"Answering the migration prompt (or supplying an EXTERNAL_HOST/ media location value) with a relative path such as './mnt/photos' or 'photos'; the source './' prefix is stripped but the target must still be absolute.","commonSituations":"Copy-pasting a relative Docker volume path; forgetting a leading slash; running the command on a host where the intended mount is only valid relative to a working directory.","solutions":["Provide the target as a fully qualified path, e.g. /usr/src/app/external/mount/photos or /mnt/photos.","Resolve the intended directory first (realpath/readlink -f) and paste the absolute result.","Make sure the path matches what the Immich container sees (container-internal absolute path, not host path)."],"exampleFix":"// before\nconst targetFolder = './photos';            // throws: Target media location must be an absolute path\n// after\nconst targetFolder = '/usr/src/app/external/photos';","handlingStrategy":"validation","validationCode":"import { isAbsolute, resolve } from 'path';\n// Validate the target folder before starting the migration\nif (!isAbsolute(targetFolder)) {\n  targetFolder = resolve(process.cwd(), targetFolder); // or prompt again\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always supply paths starting with '/' for the migration target.","Use realpath/readlink to canonicalize mounts before pasting them.","Remember container-internal paths differ from host paths in Docker setups."],"tags":["cli","paths","migration","validation"],"backgroundTag":"invalid-argument-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"}