{"record":{"id":"d28444429143dd06","repo":"vectordotdev/vector","slug":"changelog-fragment-is-invalid-filename-must-be-name-type-md","errorCode":null,"errorMessage":"Changelog fragment {} is invalid (filename must be <name>.<type>.md)","messagePattern":"Changelog fragment (.+?) is invalid \\(filename must be <name>\\.<type>\\.md\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"vdev/src/commands/release/generate_cue.rs","lineNumber":357,"sourceCode":"        .filter(|p| p.file_name().and_then(|n| n.to_str()) != Some(\"README.md\"))\n        .collect();\n    paths.sort();\n    for path in paths {\n        let mut entry = parse_changelog_fragment(&path)?;\n        entry.pr_numbers = lookup_pull_requests(repo_root, &path, pull_request_metadata)?;\n        entries.push(entry);\n    }\n    Ok(entries)\n}\n\nfn parse_changelog_fragment(path: &Path) -> Result<ChangelogEntry> {\n    let stem = path\n        .file_stem()\n        .and_then(|n| n.to_str())\n        .ok_or_else(|| anyhow!(\"Bad fragment filename: {}\", path.display()))?;\n    let parts: Vec<&str> = stem.split('.').collect();\n    if parts.len() != 2 {\n        bail!(\n            \"Changelog fragment {} is invalid (filename must be <name>.<type>.md)\",\n            path.display()\n        );\n    }\n    let fragment_type = parts[1];\n    let Some(entry) = FRAGMENT_TYPES.iter().find(|t| t.name == fragment_type) else {\n        bail!(\n            \"Changelog fragment {} has unrecognized type '{}' (valid types: {})\",\n            path.display(),\n            fragment_type,\n            FRAGMENT_TYPES\n                .iter()\n                .map(|t| t.name)\n                .collect::<Vec<_>>()\n                .join(\"|\")\n        );\n    };\n    let breaking = entry.breaking;","sourceCodeStart":339,"sourceCodeEnd":375,"githubUrl":"https://github.com/vectordotdev/vector/blob/0d4ab78a4f0d9c9e5d03a50108a2ae4d2f4b2460/vdev/src/commands/release/generate_cue.rs#L339-L375","documentation":"Changelog fragment filenames must follow the strict `<name>.<type>.md` pattern. `parse_changelog_fragment` splits the file stem on '.' and requires exactly two parts; otherwise the fragment is rejected because its type cannot be determined.","triggerScenarios":"Placing a file in `changelog.d/` whose stem contains zero or more than one dot, e.g. `my-fix.md`, `my.fix.extra.md`, or `archive.tar.md`.","commonSituations":"Naming a fragment like a regular markdown note (`notes.md`); including a version number with dots in the name (`fix-0.45.md`); stray editor or backup files landing in `changelog.d/`.","solutions":["Rename the fragment to exactly one dot: `<name>.<type>.md`, e.g. `my-fix.enhancement.md`.","Remove non-fragment files (notes, backups, editor droppings) from `changelog.d/`.","Check `changelog.d/README.md` for the valid fragment types and naming rules."],"exampleFix":"// before\nchangelog.d/fix-0.45.md\n// after\nchangelog.d/fix-0.45.bug.md   # or rename without inner dots, e.g. fix-0-45.bug.md","handlingStrategy":"validation","validationCode":"name=$(basename \"$f\" .md); [[ \"$name\" == *.* && \"$(echo \"$name\" | tr -cd '.' | wc -c)\" -eq 1 ]] || echo \"bad fragment name: $f\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Follow the `<name>.<type>.md` naming rule from changelog.d/README.md.","Never place ordinary notes or backup files in changelog.d/.","Add a CI lint that validates fragment filenames on every PR."],"tags":["cli","changelog","naming-convention"],"backgroundTag":"invalid-argument-format","analyzedSha":"0d4ab78a4f0d9c9e5d03a50108a2ae4d2f4b2460","analyzedAt":"2026-09-16T02:53:35.741Z","contentChangedAt":"2026-09-16T02:53:35.741Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}