{"record":{"id":"8eae77aedf601fb2","repo":"vectordotdev/vector","slug":"bad-fragment-filename","errorCode":null,"errorMessage":"Bad fragment filename: {}","messagePattern":"Bad fragment filename: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"vdev/src/commands/release/generate_cue.rs","lineNumber":354,"sourceCode":"    let mut paths: Vec<PathBuf> = fs::read_dir(dir)?\n        .filter_map(|e| e.ok().map(|e| e.path()))\n        .filter(|p| p.extension().is_some_and(|x| x == \"md\"))\n        .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(\"|\")","sourceCodeStart":336,"sourceCodeEnd":372,"githubUrl":"https://github.com/vectordotdev/vector/blob/0d4ab78a4f0d9c9e5d03a50108a2ae4d2f4b2460/vdev/src/commands/release/generate_cue.rs#L336-L372","documentation":"vdev's changelog fragment parser derives the PR/type suffix by splitting the fragment filename stem on '.'. This error fires when the path has no file stem that can be represented as UTF-8 (e.g. a directory or non-UTF-8 name), so no usable stem exists. It is an early guard before the stricter `<name>.<type>` format check.","triggerScenarios":"Calling read_changelog_fragments (during release CUE generation) over a changelog.d directory that contains a path whose file_stem() is None (a directory or '..' path) or whose stem is not valid UTF-8.","commonSituations":"Globbing picks up a non-UTF-8 filename created by a tool or download; someone placed a directory inside changelog.d; filenames produced on a filesystem with non-UTF-8 bytes.","solutions":["Inspect the changelog.d directory and remove/rename any non-UTF-8 or path-like entries (e.g. `find changelog.d | grep -vP '[\\x00-\\x7F]'`).","Ensure only `*.md` files following `<name>.<type>.md` naming live in changelog.d.","Rename the offending file to a plain UTF-8 name before re-running the release command."],"exampleFix":"// before\nmv 'changelog.d/fix?pat<04>.md' .   # non-UTF-8 bytes in name\n// after\nmv 'changelog.d/fix-pat04.md' .","handlingStrategy":"validation","validationCode":"fn has_valid_stem(p: &std::path::Path) -> bool {\n    p.file_stem().and_then(|n| n.to_str()).is_some()\n}\n// filter the glob results before running the release command","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep only plain ASCII `<name>.<type>.md` files in changelog.d","Add a CI lint rejecting non-UTF-8 filenames in changelog.d","Never place directories or dot-paths inside changelog.d"],"tags":["rust","cli","naming"],"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"}