{"record":{"id":"a33e2f9e939ae007","repo":"gastownhall/beads","slug":"invalid-file-type-only-md-and-markdown-files-ar","errorCode":null,"errorMessage":"invalid file type: only .md and .markdown files are supported","messagePattern":"invalid file type: only \\.md and \\.markdown files are supported","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/markdown.go","lineNumber":119,"sourceCode":"\t\tissue.Dependencies = parseDependencies(content)\n\t}\n}\n\n// validateMarkdownPath validates and cleans a markdown file path to prevent security issues.\n// It checks for directory traversal attempts and ensures the file is a markdown file.\nfunc validateMarkdownPath(path string) (string, error) {\n\t// Clean the path\n\tcleanPath := filepath.Clean(path)\n\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","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/markdown.go#L101-L137","documentation":"The markdown import path only accepts files with a `.md` or `.markdown` extension (case-insensitive). validateMarkdownPath inspects filepath.Ext of the cleaned path and rejects anything else, because the parser expects markdown issue templates.","triggerScenarios":"Passing a file with any other extension (e.g. `.txt`, `.mdown`, `.MD` is fine but `.markdown5` is not) or no extension to the markdown import API.","commonSituations":"Importing a `.txt` issue dump; a generated temp file with a random suffix; renaming scripts stripping the extension; Windows files created without extension.","solutions":["Rename the file to end in .md or .markdown","Copy the content into a new .md file and import that","If it is markdown under another extension, create a symlink/copy with a .md name"],"exampleFix":"// before\nparseMarkdownFile(\"issues.txt\")\n// after\nparseMarkdownFile(\"issues.md\")   // or: cp issues.txt issues.md","handlingStrategy":"validation","validationCode":"ext := strings.ToLower(filepath.Ext(path))\nif ext != \".md\" && ext != \".markdown\" {\n\treturn fmt.Errorf(\"%s is not a markdown file\", path)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always save import files with .md or .markdown extensions","Normalize generated files' extensions before import","Validate extensions in scripts before invoking bd"],"tags":["file-extension","validation","markdown"],"backgroundTag":"unsupported-file-type","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}