vectordotdev/vector · error

invalid fragment filename

Error message

invalid fragment filename '{filename}': expected '<unique_name>.<fragment_type>.md'

What it means

A file in the changelog fragments directory does not follow the required naming pattern `<unique_name>.<fragment_type>.md` (exactly three dot-separated parts). The checker cannot infer the fragment type from the filename, so validation aborts.

Solutions

  1. Rename the file to `your_name.fragment_type.md`, e.g. `jdoe.new-feature.md`.
  2. Remove any editor backup/swap files from the changelog.d directory.
  3. Use the scaffolder command to generate a correctly named fragment.

Example fix

// before
changelog.d/my-change.md
// after
changelog.d/jdoe.new-feature.md
Defensive patterns

Strategy: validation

Validate before calling

const FRAGMENT_TYPES: [&str; 5] = ["new-feature", "enhancement", "bugfix", "breaking", "deprecation"];
for f in std::fs::read_dir("changelog.d")? {
    let name = f?.file_name().to_string_lossy().into_owned();
    let parts: Vec<&str> = name.split('.').collect();
    assert_eq!(parts.len(), 3, "bad fragment filename: {name}");
}

Prevention

When it happens

Trigger: Running `vdev check changelog-fragments` when a file in changelog.d/ has a name that doesn't split into exactly three dot-separated segments, e.g. `my-change.md`, `my.change.md.bak`, or `feature.new-feature.md.txt`.

Common situations: Manually creating a fragment without using the scaffolder; renaming a fragment with a text editor that appends `.txt` or `.bak`; editors leaving swap files 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


AI-assisted analysis of vectordotdev/vector@bdb87aeaa4 (2026-09-16). Data as JSON: /api/errors/6821112ce4ac82d5. Report an issue: GitHub.

Appendix: source

Thrown at vdev/src/commands/check/changelog_fragments.rs:169

    let out = git::run_and_check_output(&[
        "diff",
        "--name-only",
        &filter_arg,
        "--merge-base",
        merge_base,
        CHANGELOG_DIR,
    ])?;
    Ok(out
        .lines()
        .filter(|l| !l.trim().is_empty())
        .map(PathBuf::from)
        .collect())
}

fn validate_filename(filename: &str) -> Result<&'static FragmentType> {
    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)

View on GitHub (pinned to bdb87aeaa4)