vectordotdev/vector · error

Duplicate deprecation fragments for `what

Error message

Duplicate deprecation fragments for `what`: '{}' (in {} and {})

What it means

When scanning changelog.d for pending deprecation fragments, each `what` identifier must be unique — two fragments announcing the same deprecation would publish it twice. `read_deprecation_fragments` builds a map of `what` -> filename and bails if a duplicate is inserted. The error names both conflicting files.

Solutions

  1. Find the two files named in the error and delete the redundant one
  2. Change the `what` of one fragment if they genuinely describe different deprecations
  3. Search changelog.d for the `what` string to confirm only one fragment remains
  4. Re-run the deprecation sync/check after cleanup

Example fix

// before (two files)
# changelog.d/remove_old_api.md  what: old_api
# changelog.d/deprecate_old_api.md what: old_api
// after
# changelog.d/deprecate_old_api.md what: old_api   # keep only one
Defensive patterns

Strategy: validation

Validate before calling

// before committing a fragment, ensure uniqueness of `what` across changelog.d
let whats: Vec<&str> = files.iter().map(|f| parse_what(f)).collect();
assert_eq!(whats.len(), whats.iter().collect::<std::collections::HashSet<_>>().len());

Prevention

When it happens

Trigger: Running any consumer (append_enacted, rendered_json, sync_deprecations_cue, tests) that triggers `read_deprecation_fragments` when two fragment files in changelog.d declare the same `what` value in frontmatter.

Common situations: Copying an existing fragment and forgetting to change the `what` field; two PRs adding fragments for the same feature; rebasing leaving both an old and renamed fragment file behind.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


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

Appendix: source

Thrown at vdev/src/utils/deprecation.rs:136

        return Ok(Vec::new());
    }
    let mut paths: Vec<PathBuf> = fs::read_dir(dir)?
        .filter_map(|e| e.ok().map(|e| e.path()))
        .filter(|p| is_deprecation_fragment(p))
        .collect();
    paths.sort();
    let entries: Vec<DeprecationEntry> = paths
        .into_iter()
        .map(|p| parse_deprecation_fragment(&p))
        .collect::<Result<_>>()?;

    // Reject duplicate `what` across pending fragments. A feature has one
    // identity; two fragments with the same `what` would publish the same
    // deprecation twice.
    let mut seen: std::collections::HashMap<&str, &str> = std::collections::HashMap::new();
    for e in &entries {
        if let Some(prev) = seen.insert(e.what.as_str(), e.filename.as_str()) {
            bail!(
                "Duplicate deprecation fragments for `what`: '{}' (in {} and {})",
                e.what,
                prev,
                e.filename
            );
        }
    }
    Ok(entries)
}

fn is_deprecation_fragment(path: &Path) -> bool {
    let Some(name) = path.file_name().and_then(|n| n.to_str()) else {
        return false;
    };
    if name == "README.md" {
        return false;
    }
    if !std::path::Path::new(name)

View on GitHub (pinned to bdb87aeaa4)