vectordotdev/vector · error
invalid fragment filename
Error message
invalid fragment filename '{filename}': extension must be markdown (.md). What it means
Fired by validate_filename when a changelog fragment file's extension is not '.md'. The checker splits the filename on '.' and requires exactly three parts '<unique_name>.<fragment_type>.md'; a file with a different extension (e.g. 'foo.breaking.txt' or editor backups) fails this shape check and is rejected as an invalid fragment filename.
Solutions
- Rename the file so it ends in `.md`.
- Move non-Markdown notes out of the changelog.d directory.
- Delete leftover editor backup files from changelog.d/.
Example fix
// before changelog.d/jdoe.new-feature.markdown // after changelog.d/jdoe.new-feature.md
Defensive patterns
Strategy: validation
Validate before calling
let name = "jdoe.new-feature.markdown";
assert_eq!(name.split('.').last().unwrap(), "md", "fragment must end in .md"); Prevention
- Only write fragments as plain Markdown with a .md extension.
- Avoid MDX or other Markdown variants in changelog.d/.
- Exclude changelog.d/ from editor backup plugins.
When it happens
Trigger: Running `vdev check changelog-fragments` with files like `jdoe.new-feature.mdx`, `jdoe.new-feature.markdown`, or `jdoe.new-feature.md.orig` (parts.len()==3 but parts[2] != "md").
Common situations: Authoring in MDX; saving with a text editor that appends an extension; backup tools appending suffixes like `.orig` in changelog.d/.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- invalid fragment filename
- invalid fragment filename
- duplicate upgrade-guide anchor '#
- invalid breaking fragment
- invalid breaking fragment
AI-assisted analysis of vectordotdev/vector@bdb87aeaa4 (2026-09-16).
Data as JSON: /api/errors/7da5da86e8edd11b.
Report an issue: GitHub.
Appendix: source
Thrown at vdev/src/commands/check/changelog_fragments.rs:185
let parts: Vec<&str> = filename.split('.').collect();
if parts.len() != 3 {
bail!(
"invalid fragment filename '{filename}': expected '<unique_name>.<fragment_type>.md'"
);
}
let fragment_type = parts[1];
let Some(known) = FRAGMENT_TYPES.iter().find(|t| t.name == fragment_type) else {
bail!(
"invalid fragment filename '{filename}': fragment type must be one of ({}).",
FRAGMENT_TYPES
.iter()
.map(|t| t.name)
.collect::<Vec<_>>()
.join("|")
);
};
if parts[2] != "md" {
bail!("invalid fragment filename '{filename}': extension must be markdown (.md).");
}
Ok(known)
}
fn validate_contents(
path: &std::path::Path,
filename: &str,
fragment_type: &FragmentType,
) -> Result<()> {
let content = std::fs::read_to_string(path)?;
// Match generate_cue.rs, which reads `lines().last()` verbatim: the authors
// line must be the last line, no trailing blank lines allowed.
let last_line = content.lines().last().unwrap_or("");
let Some(names) = last_line.strip_prefix("authors: ") else {
bail!(
"invalid fragment contents for '{filename}': last line must be 'authors: <name> [<name> ...]' (no trailing blank lines)."
);View on GitHub (pinned to bdb87aeaa4)