homebridge/homebridge · error
Storage path was already accessed and cannot be changed anym
Error message
Storage path was already accessed and cannot be changed anymore. Try initializing your custom storage path earlier!
What it means
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.
Source
Thrown at src/user.ts:35
}
static matterPath(): string {
return join(User.storagePath(), 'matter') // matter data is stored here
}
static cachedAccessoryPath(): string {
return join(User.storagePath(), 'accessories')
}
static storagePath(): string {
User.storageAccessed = true
return User.customStoragePath ? User.customStoragePath : join(homedir(), '.homebridge')
}
public static setStoragePath(...storagePathSegments: string[]): void {
if (User.storageAccessed) {
throw new Error('Storage path was already accessed and cannot be changed anymore. Try initializing your custom storage path earlier!')
}
User.customStoragePath = resolve(...storagePathSegments)
}
}
View on GitHub (pinned to edf5493034)
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)
Example fix
// before
const { HomebridgeAPI } = await import('./api.js')
User.setStoragePath('/data/homebridge')
// after
User.setStoragePath('/data/homebridge')
const { HomebridgeAPI } = await import('./api.js') Defensive patterns
Strategy: validation
Validate before calling
// Ensure custom path is set before anything can access storage:
import { User } from './user.js'
User.setStoragePath(process.env.HOMEBRIDGE_STORAGE || '/var/lib/homebridge')
// only then import/construct Server, BridgeService, Logger, etc. Try / catch
try {
User.setStoragePath(customPath)
} catch (e) {
if ((e as Error).message.includes('Storage path was already accessed')) {
console.error('Move setStoragePath to the very start of your bootstrap sequence')
}
throw e
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Unexpected accessory registration. Plugin ${pluginIdentifier
- Unexpected platform registration. Plugin ${pluginIdentifier
- ${cannotAction} before Homebridge has finished launching. Do
- ${cannotAction}: Matter is not enabled for this bridge. api.
- Failed to unregister accessory: ${error}
AI-assisted analysis of homebridge/homebridge@edf5493034 (2026-08-30).
Data as JSON: /api/errors/5be7a7f7085de762.
Report an issue: GitHub.