{"record":{"id":"f89df9407deabdb4","repo":"gastownhall/beads","slug":"create-recipes-toml-w","errorCode":null,"errorMessage":"create recipes.toml: %w","messagePattern":"create recipes\\.toml: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/recipes/recipes.go","lineNumber":250,"sourceCode":"\t\tuserRecipes.Recipes = make(map[string]Recipe)\n\t}\n\n\t// Add/update the recipe\n\tuserRecipes.Recipes[name] = Recipe{\n\t\tName: name,\n\t\tPath: path,\n\t\tType: TypeFile,\n\t}\n\n\t// Ensure directory exists\n\tif err := os.MkdirAll(beadsDir, 0o700); err != nil {\n\t\treturn fmt.Errorf(\"create beads dir: %w\", err)\n\t}\n\n\t// Write back\n\tf, err := os.Create(recipesPath) // #nosec G304 -- path is constructed from validated beadsDir\n\tif err != nil {\n\t\treturn fmt.Errorf(\"create recipes.toml: %w\", err)\n\t}\n\tdefer f.Close()\n\n\tencoder := toml.NewEncoder(f)\n\tif err := encoder.Encode(userRecipes); err != nil {\n\t\treturn fmt.Errorf(\"encode recipes.toml: %w\", err)\n\t}\n\n\treturn nil\n}\n\n// ListRecipeNames returns sorted list of all recipe names.\nfunc ListRecipeNames(beadsDir string) ([]string, error) {\n\trecipes, err := GetAllRecipes(beadsDir)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n","sourceCodeStart":232,"sourceCodeEnd":268,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/recipes/recipes.go#L232-L268","documentation":"After the recipes directory is ensured, SaveUserRecipe creates/truncates recipes.toml; if os.Create fails the error is wrapped and nothing is written.","triggerScenarios":"os.Create(<beadsDir>/recipes.toml) fails due to permission denied on the directory, a directory named recipes.toml existing in its place, or a read-only filesystem.","commonSituations":"recipes.toml exists as a directory (odd but possible after bad scripting), .beads owned by root, or running on a read-only checkout.","solutions":["Check that .beads/recipes.toml is not a directory; remove or rename it if so","Fix .beads directory permissions so the current user can write (chmod/chown)","Verify the filesystem is writable (not mounted read-only)"],"exampleFix":"// before\n.beads/recipes.toml/  (directory)\n// after\nrm -rf .beads/recipes.toml && bd recipe save ...","handlingStrategy":"validation","validationCode":"path := filepath.Join(beadsDir, \"recipes.toml\")\nif info, err := os.Stat(path); err == nil && !info.Mode().IsRegular() {\n\treturn fmt.Errorf(\"%s is not a regular file\", path)\n}","typeGuard":null,"tryCatchPattern":"if err := SaveUserRecipe(ctx, beadsDir, recipe); err != nil {\n\tvar pe *fs.PathError\n\tif errors.As(errors.Unwrap(err), &pe) && errors.Is(pe, fs.ErrPermission) {\n\t\treturn fmt.Errorf(\"cannot write %s: %w\", pe.Path, err)\n\t}\n\treturn err\n}","preventionTips":["Keep .beads owned and writable by the current user","Don't create directories where file paths are expected","Check for read-only filesystems in CI containers"],"tags":["filesystem","permissions","write"],"backgroundTag":"file-write-permission-denied","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}