{"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":"Error","httpStatus":null,"severity":"error","filePath":"server/src/services/cli.service.ts","lineNumber":219,"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":201,"sourceCodeEnd":235,"githubUrl":"https://github.com/immich-app/immich/blob/199723261c6ffa897fec8ccdaea6359e39c37cc3/server/src/services/cli.service.ts#L201-L235","documentation":"Thrown (plain Error) by CliService during the storage-location migration flow. After stripping a leading './' from the old value, it requires the new value to be absolute; node's path.isAbsolute must return true. This prevents migrations from writing to a relative (and thus unpredictable) target.","triggerScenarios":"Invoking the CLI storage-path migration with a newValue that is a relative path (e.g. './photos' or 'photos') rather than a rooted path like '/mnt/photos'.","commonSituations":"Docker/relative-path configs; copying a path from a config that used './' notation; misconfigured volume mount path passed verbatim.","solutions":["Provide an absolute target path, e.g. '/mnt/immich/library' or '/usr/src/app/upload'.","Resolve the path with path.resolve() before passing it so './x' becomes absolute.","Verify the target directory exists and is writable by the server process."],"exampleFix":"// before\nawait cliService['migrateFilePaths']({ oldValue: './upload', newValue: 'photos', confirm });\n\n// after\nconst { isAbsolute, resolve } = require('path');\nlet target = newValue;\nif (!isAbsolute(target)) target = resolve(target);\n// target === process.cwd() + '/photos'\nawait cliService['migrateFilePaths']({ oldValue: './upload', newValue: target, confirm });","handlingStrategy":"validation","validationCode":"const { isAbsolute, resolve } = require('path');\nconst target = isAbsolute(newValue) ? newValue : resolve(newValue);\nif (!isAbsolute(target)) throw new Error('Target media location must be absolute');","typeGuard":"function isAbsolutePath(p: string): boolean {\n  const { isAbsolute } = require('path');\n  return isAbsolute(p);\n}","tryCatchPattern":null,"preventionTips":["Always pass rooted paths (e.g. '/mnt/immich/library') to storage migration.","Resolve relative inputs with path.resolve() before submitting.","Confirm the target directory exists and is writable by the server."],"tags":["cli","storage","filesystem","path","migration"],"backgroundTag":null,"analyzedSha":"199723261c6ffa897fec8ccdaea6359e39c37cc3","analyzedAt":"2026-08-12T04:54:27.085Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}