{"record":{"id":"5be7a7f7085de762","repo":"homebridge/homebridge","slug":"storage-path-was-already-accessed-and-cannot-be-ch","errorCode":null,"errorMessage":"Storage path was already accessed and cannot be changed anymore. Try initializing your custom storage path earlier!","messagePattern":"Storage path was already accessed and cannot be changed anymore\\. Try initializing your custom storage path earlier!","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/user.ts","lineNumber":35,"sourceCode":"  }\n\n  static matterPath(): string {\n    return join(User.storagePath(), 'matter') // matter data is stored here\n  }\n\n  static cachedAccessoryPath(): string {\n    return join(User.storagePath(), 'accessories')\n  }\n\n  static storagePath(): string {\n    User.storageAccessed = true\n\n    return User.customStoragePath ? User.customStoragePath : join(homedir(), '.homebridge')\n  }\n\n  public static setStoragePath(...storagePathSegments: string[]): void {\n    if (User.storageAccessed) {\n      throw new Error('Storage path was already accessed and cannot be changed anymore. Try initializing your custom storage path earlier!')\n    }\n\n    User.customStoragePath = resolve(...storagePathSegments)\n  }\n}\n","sourceCodeStart":17,"sourceCodeEnd":41,"githubUrl":"https://github.com/homebridge/homebridge/blob/edf54930340d67cade23d01abd41b03cd9621e8b/src/user.ts#L17-L41","documentation":"User.setStoragePath() lets embedders (like config-ui-x or tests) redirect Homebridge's storage directory, but only before anything reads the storage path. Once any code calls User.storagePath(), the `storageAccessed` flag is set and the path is considered frozen; later calls to setStoragePath throw this Error because cached state may already depend on the old path.","triggerScenarios":"Calling User.setStoragePath() after another module already resolved the storage path (e.g. after Logger or storageService initialization); constructing a BridgeService or Server before setting a custom path.","commonSituations":"Embedding Homebridge in a custom app where setStoragePath is invoked late in a boot sequence; tests that import modules with module-level side effects touching storagePath before arranging the test.","solutions":["Call User.setStoragePath() as the very first action after importing the modules, before creating Server/BridgeService/Logger","Defer imports that trigger storage-path access until after setStoragePath (dynamic import())","If the path truly must change, restart the process with the new path set at startup (or use the -U CLI flag)"],"exampleFix":"// before\nconst { HomebridgeAPI } = await import('./api.js')\nUser.setStoragePath('/data/homebridge')\n// after\nUser.setStoragePath('/data/homebridge')\nconst { HomebridgeAPI } = await import('./api.js')","handlingStrategy":"validation","validationCode":"// Ensure custom path is set before anything can access storage:\nimport { User } from './user.js'\nUser.setStoragePath(process.env.HOMEBRIDGE_STORAGE || '/var/lib/homebridge')\n// only then import/construct Server, BridgeService, Logger, etc.","typeGuard":null,"tryCatchPattern":"try {\n  User.setStoragePath(customPath)\n} catch (e) {\n  if ((e as Error).message.includes('Storage path was already accessed')) {\n    console.error('Move setStoragePath to the very start of your bootstrap sequence')\n  }\n  throw e\n}","preventionTips":["Set the storage path as the first line of your embedder's entry point","Avoid module-level side effects that read User.storagePath at import time","Use the -U CLI flag instead of runtime changes when launching via the CLI"],"tags":["storage","lifecycle","api-misuse"],"backgroundTag":"storage-path-locked","analyzedSha":"edf54930340d67cade23d01abd41b03cd9621e8b","analyzedAt":"2026-08-30T21:28:53.235Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}