{"record":{"id":"aafb05f3e276dbd8","repo":"JuliusBrussee/caveman","slug":"create-recovery-directory-q-w","errorCode":null,"errorMessage":"create recovery directory %q: %w","messagePattern":"create recovery directory %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mcp/cmd/caveman-mcp/main.go","lineNumber":86,"sourceCode":"// openRecoveryStore opens the shared file CCR store the proxy uses, so handles are\n// resolvable across processes. CAVEMAN_MCP_EPHEMERAL=1 forces an in-memory store\n// (no disk). The path mirrors the proxy: CAVEMAN_CCR_DB, else ~/.caveman/ccr.db.\nfunc openRecoveryStore() (*ccr.Store, error) {\n\tif os.Getenv(\"CAVEMAN_MCP_EPHEMERAL\") == \"1\" {\n\t\treturn ccr.OpenMemory()\n\t}\n\tpath := os.Getenv(\"CAVEMAN_CCR_DB\")\n\tif path == \"\" {\n\t\thome := os.Getenv(\"CAVEMAN_HOME\")\n\t\tif home == \"\" {\n\t\t\th, err := os.UserHomeDir()\n\t\t\tif err != nil {\n\t\t\t\treturn ccr.OpenMemory()\n\t\t\t}\n\t\t\thome = filepath.Join(h, \".caveman\")\n\t\t}\n\t\tif err := os.MkdirAll(home, 0o700); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"create recovery directory %q: %w\", home, err)\n\t\t}\n\t\tpath = filepath.Join(home, \"ccr.db\")\n\t}\n\treturn ccr.Open(path)\n}\n","sourceCodeStart":68,"sourceCodeEnd":92,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/mcp/cmd/caveman-mcp/main.go#L68-L92","documentation":"openRecoveryStore could not create the directory that will hold the CCR recovery database (ccr.db). The wrapped os.MkdirAll error names the path and underlying OS reason (permissions, read-only fs, etc.). Without this directory the recovery store cannot be opened.","triggerScenarios":"os.MkdirAll fails on the resolved ~/.caveman (or fallback home) directory because of permissions, a read-only filesystem, or the path existing as a non-directory file.","commonSituations":"HOME set to an unwritable path in containers/cron; ~/.caveman exists as a regular file; sandboxed environments blocking writes to home.","solutions":["Check the wrapped error's path and OS reason; verify permissions on the target directory","If ~/.caveman exists as a file, remove or rename it so it can be a directory","Ensure HOME (or the override env) points to a writable location, or run with adequate privileges","Mount/write to a writable volume and set the home override accordingly"],"exampleFix":"// before: HOME=/nonexistent-writable\n// after\nexport HOME=/tmp/caveman-home && caveman-mcp","handlingStrategy":"validation","validationCode":"home := os.Getenv(\"HOME\")\nif info, err := os.Stat(filepath.Join(home, \".caveman\")); err == nil && !info.IsDir() {\n  // fix path before launching\n}\nif err := os.MkdirAll(filepath.Join(home, \".caveman\"), 0o700); err != nil { /* fix perms */ }","typeGuard":null,"tryCatchPattern":"store, err := openRecoveryStore()\nif err != nil {\n  var pe *fs.PathError\n  if errors.As(err, &pe) { log.Printf(\"fs problem at %s: %v\", pe.Path, pe.Err) }\n  os.Exit(1)\n}","preventionTips":["Ensure HOME points to a writable directory in containers/cron","Check that ~/.caveman is not a regular file","Pre-create or verify the directory in deployment scripts","Run services with a user that owns its home directory"],"tags":["filesystem","directory","mkdir","recovery-store"],"backgroundTag":"mkdir-permission-denied","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}