{"record":{"id":"f51bcbff40e637e0","repo":"gastownhall/beads","slug":"path-is-a-directory-not-a-file","errorCode":null,"errorMessage":"path is a directory, not a file","messagePattern":"path is a directory, not a file","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/markdown.go","lineNumber":128,"sourceCode":"\n\t// Prevent directory traversal\n\tif strings.Contains(cleanPath, \"..\") {\n\t\treturn \"\", fmt.Errorf(\"invalid file path: directory traversal not allowed\")\n\t}\n\n\t// Ensure it's a markdown file\n\text := strings.ToLower(filepath.Ext(cleanPath))\n\tif ext != \".md\" && ext != \".markdown\" {\n\t\treturn \"\", fmt.Errorf(\"invalid file type: only .md and .markdown files are supported\")\n\t}\n\n\t// Check file exists and is not a directory\n\tinfo, err := os.Stat(cleanPath)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"cannot access file: %w\", err)\n\t}\n\tif info.IsDir() {\n\t\treturn \"\", fmt.Errorf(\"path is a directory, not a file\")\n\t}\n\n\treturn cleanPath, nil\n}\n\n// parseMarkdownFile parses a markdown file and extracts issue templates.\n// Expected format:\n//\n//\t## Issue Title\n//\tDescription text...\n//\n//\t### Priority\n//\t2\n//\n//\t### Type\n//\tfeature\n//\n//\t### Description","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/markdown.go#L110-L146","documentation":"os.Stat succeeds but reports the path is a directory; the markdown parser requires a regular file, so validateMarkdownPath rejects directories explicitly. This prevents confusing downstream scanner failures when a directory is handed to the import.","triggerScenarios":"Passing a directory path ending in `.md`/`.markdown` (e.g. `notes/` inside a directory literally named `something.md`) or simply a directory to the markdown import API.","commonSituations":"Pointing import at a folder of markdown files instead of a single file; a directory named `docs.md`; globbing that expanded to a directory.","solutions":["Pass an individual .md file path, not a directory","Loop over the directory's .md files and import each one","Rename the directory if it misleadingly has a markdown extension"],"exampleFix":"// before\nparseMarkdownFile(\"docs/issues.md/\")\n// after\nparseMarkdownFile(\"docs/issues.md/backend.md\")   // a file inside the directory","handlingStrategy":"validation","validationCode":"fi, err := os.Stat(path)\nif err == nil && fi.IsDir() {\n\treturn fmt.Errorf(\"%s is a directory; pass a file\", path)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check the target is a file, not a directory, before import","Beware directories named with .md suffixes","Iterate directory contents yourself instead of passing the directory"],"tags":["filesystem","validation","wrong-argument-type"],"backgroundTag":"path-is-a-directory","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}