{"record":{"id":"6e9956296ea84aa6","repo":"charmbracelet/crush","slug":"cannot-reload-working-directory-not-set","errorCode":null,"errorMessage":"cannot reload: working directory not set","messagePattern":"cannot reload: working directory not set","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/config/store.go","lineNumber":1168,"sourceCode":"\t}\n\tslices.Sort(s.trackedConfigPaths)\n\n\t// Capture initial snapshots\n\ts.RefreshStalenessSnapshot()\n}\n\n// captureStalenessSnapshot is an alias for CaptureStalenessSnapshot for internal use.\nfunc (s *ConfigStore) captureStalenessSnapshot(paths []string) {\n\ts.CaptureStalenessSnapshot(paths)\n}\n\n// ReloadFromDisk re-runs the config load/merge flow and updates the in-memory\n// config atomically. It rebuilds the staleness snapshot after successful reload.\n// On failure, the store state is rolled back to its previous state.\n// Concurrent calls are serialised via writeMu.\nfunc (s *ConfigStore) ReloadFromDisk(ctx context.Context) error {\n\tif s.workingDir == \"\" {\n\t\treturn fmt.Errorf(\"cannot reload: working directory not set\")\n\t}\n\ts.writeMu.Lock()\n\tdefer s.writeMu.Unlock()\n\treturn s.reloadFromDiskLocked(ctx)\n}\n\n// reloadFromDiskLocked performs the actual reload. Caller must hold writeMu.\nfunc (s *ConfigStore) reloadFromDiskLocked(ctx context.Context) error {\n\t// Migrate deprecated disable_notifications before reloading config.\n\tmigrateDisableNotifications()\n\n\tconfigPaths := lookupConfigs(s.workingDir)\n\tcfg, loadedPaths, err := loadFromConfigPaths(ctx, configPaths)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to reload config: %w\", err)\n\t}\n\n\t// Apply defaults (using existing data directory if set)","sourceCodeStart":1150,"sourceCodeEnd":1186,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/config/store.go#L1150-L1186","documentation":"ReloadFromDisk re-runs the whole config load/merge flow against the store's workingDir. If the store was constructed without a working directory, there is no path to look config files up from, so it refuses immediately with this error before taking the write lock.","triggerScenarios":"Calling ConfigStore.ReloadFromDisk(ctx) on a store created with an empty workingDir — e.g. a store built programmatically in tests or via an API path that did not pass the cwd.","commonSituations":"Embedding the config store in another tool without wiring the working directory; test fixtures that build a bare ConfigStore{}.","solutions":["Construct the store with a valid working directory (the project cwd).","Skip reload when workingDir is empty: guard the call site.","Recreate the store with the proper constructor that captures the cwd."],"exampleFix":"// before\nstore.ReloadFromDisk(ctx) // panics-free but errors: no workingDir\n// after\nif store.WorkingDir() != \"\" {\n    store.ReloadFromDisk(ctx)\n}","handlingStrategy":"type-guard","validationCode":"if store.WorkingDir() == \"\" { store = NewConfigStore(cwd) }","typeGuard":"func canReload(s *ConfigStore) bool { return s != nil && s.WorkingDir() != \"\" }","tryCatchPattern":"if err := store.ReloadFromDisk(ctx); err != nil && strings.Contains(err.Error(), \"working directory not set\") {\n    store = NewConfigStore(os.Getenv(\"PWD\"))\n}","preventionTips":["Always construct the store via its constructor with cwd","Skip reload paths in embedded/test contexts without a cwd"],"tags":["configuration","reload","initialization"],"backgroundTag":"working-directory-not-set","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}