gastownhall/beads · error

invalid file type: only .md and .markdown files are supporte

Error message

invalid file type: only .md and .markdown files are supported

What it means

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.

Source

Thrown at cmd/bd/markdown.go:119

		issue.Dependencies = parseDependencies(content)
	}
}

// validateMarkdownPath validates and cleans a markdown file path to prevent security issues.
// It checks for directory traversal attempts and ensures the file is a markdown file.
func validateMarkdownPath(path string) (string, error) {
	// Clean the path
	cleanPath := filepath.Clean(path)

	// Prevent directory traversal
	if strings.Contains(cleanPath, "..") {
		return "", fmt.Errorf("invalid file path: directory traversal not allowed")
	}

	// Ensure it's a markdown file
	ext := strings.ToLower(filepath.Ext(cleanPath))
	if ext != ".md" && ext != ".markdown" {
		return "", fmt.Errorf("invalid file type: only .md and .markdown files are supported")
	}

	// Check file exists and is not a directory
	info, err := os.Stat(cleanPath)
	if err != nil {
		return "", fmt.Errorf("cannot access file: %w", err)
	}
	if info.IsDir() {
		return "", fmt.Errorf("path is a directory, not a file")
	}

	return cleanPath, nil
}

// parseMarkdownFile parses a markdown file and extracts issue templates.
// Expected format:
//
//	## Issue Title

View on GitHub (pinned to 71377f2769)

Solutions

  1. Rename the file to end in .md or .markdown
  2. Copy the content into a new .md file and import that
  3. If it is markdown under another extension, create a symlink/copy with a .md name

Example fix

// before
parseMarkdownFile("issues.txt")
// after
parseMarkdownFile("issues.md")   // or: cp issues.txt issues.md
Defensive patterns

Strategy: validation

Validate before calling

ext := strings.ToLower(filepath.Ext(path))
if ext != ".md" && ext != ".markdown" {
	return fmt.Errorf("%s is not a markdown file", path)
}

Prevention

When it happens

Trigger: 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.

Common situations: Importing a `.txt` issue dump; a generated temp file with a random suffix; renaming scripts stripping the extension; Windows files created without extension.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/a33e2f9e939ae007. Report an issue: GitHub.