{"record":{"id":"e1812479bae96bf0","repo":"gastownhall/beads","slug":"failed-to-create-beads-directory-w-e18124","errorCode":null,"errorMessage":"failed to create .beads directory: %w","messagePattern":"failed to create \\.beads directory: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/audit/audit.go","lineNumber":90,"sourceCode":"}\n\nfunc truthy(raw string) bool {\n\tswitch strings.ToLower(strings.TrimSpace(raw)) {\n\tcase \"1\", \"t\", \"true\", \"y\", \"yes\", \"on\":\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\n// EnsureFile creates .beads/interactions.jsonl if it does not exist.\nfunc EnsureFile() (string, error) {\n\tp, err := Path()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tif err := os.MkdirAll(filepath.Dir(p), 0700); err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to create .beads directory: %w\", err)\n\t}\n\tif ensureFileBeforeCreateHook != nil {\n\t\tensureFileBeforeCreateHook(p)\n\t}\n\tf, err := os.OpenFile(p, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0644) // nolint:gosec // JSONL is intended to be shared via git across clones/tools.\n\tif err == nil {\n\t\tif closeErr := f.Close(); closeErr != nil {\n\t\t\treturn \"\", fmt.Errorf(\"failed to close interactions log: %w\", closeErr)\n\t\t}\n\t\treturn p, nil\n\t}\n\tif !errors.Is(err, os.ErrExist) {\n\t\treturn \"\", fmt.Errorf(\"failed to create interactions log: %w\", err)\n\t}\n\treturn p, nil\n}\n\n// Append appends an event to .beads/interactions.jsonl as a single JSON line.","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/audit/audit.go#L72-L108","documentation":"EnsureFile resolves the audit file path via Path(), then ensures the .beads directory exists with os.MkdirAll(dir, 0700). If the mkdir fails, the error is wrapped with 'failed to create .beads directory'. This means the audit sidecar cannot be created because its parent directory cannot be materialized.","triggerScenarios":"MkdirAll fails because a component of the path exists as a regular file, the parent is read-only, or the process lacks permission to create directories there.","commonSituations":"A stray file named '.beads' (not a directory) in the repo, read-only checkouts or mounted volumes, or running bd as a user without write access to the project or HOME.","solutions":["Check whether a file named .beads exists and remove/rename it so a directory can be created","Grant write permission on the parent directory (chown/chmod) or run as the correct user","If the volume is read-only, point the beads directory at a writable location"],"exampleFix":"// before\n$ ls -la | grep beads\n-rw-r--r--  .beads        # a file, not a directory\n// after\n$ rm .beads && bd init   # recreate .beads as a directory","handlingStrategy":"validation","validationCode":"dir := filepath.Dir(auditPath)\nif fi, err := os.Stat(dir); err == nil && !fi.IsDir() {\n    return fmt.Errorf(\"%s exists as a file; remove it so a directory can be created\", dir)\n}\nif err := os.MkdirAll(dir, 0700); err != nil { return err }","typeGuard":null,"tryCatchPattern":"p, err := audit.EnsureFile()\nif err != nil {\n    if strings.Contains(err.Error(), \"failed to create .beads directory\") {\n        return fmt.Errorf(\"check .beads is not a plain file and parent is writable: %w\", err)\n    }\n    return err\n}","preventionTips":["Never create a file named .beads; keep it a directory","Ensure the running user owns or can write the project dir","Skip audit features gracefully on read-only checkouts"],"tags":["filesystem","permissions","beads"],"backgroundTag":"mkdir-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}