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
- Find the two files named in the error and delete the redundant one
- Change the `what` of one fragment if they genuinely describe different deprecations
- Search changelog.d for the `what` string to confirm only one fragment remains
- 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
- Copy from a template but immediately change `what` to a unique identifier
- grep changelog.d for the `what` string before adding a new fragment
- Name fragment files after the `what` to make duplicates obvious in review
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
- Deprecation fragment
- Duplicate enacted entry for
- Enacted entry ' ' has removed_in ( ) that is not in a later…
- invalid breaking fragment
- invalid fragment contents for
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)