vectordotdev/vector · error
breaking fragment ' ' has an invalid anchor ' '. Add ` }`…
Error message
breaking fragment '{}' has an invalid anchor '{}'. Add `{{#some-valid-slug}}` after the title. What it means
`validate_breaking_anchors` checks every breaking-change fragment collected for the release notes and requires each title to carry a valid `{{#anchor}}` slug. The anchor validity rules are shared with `vdev check changelog-fragments` (via `commands::changelog::is_valid_anchor`), so a fragment that passed CI cannot fail here. An invalid or missing anchor aborts release-note generation.
Solutions
- Open the fragment named in the message and add or fix the `{{#valid-slug}}` after the title.
- Use lowercase kebab-case slugs (letters, digits, hyphens) matching the rules in commands::changelog::is_valid_anchor.
- Run `vdev check changelog-fragments` locally to validate anchors with the same rules before regenerating.
- Re-run `vdev release generate-cue`.
Example fix
// before (changelog.d/1234_breaking.md)
## drop the `metrics` sink {{#}}
// after
## drop the `metrics` sink {{#drop-metrics-sink}} Defensive patterns
Strategy: validation
Validate before calling
// validate a fragment anchor before committing it
const ANCHOR_RE = /\{\{#[a-z0-9]+(?:-[a-z0-9]+)*\}\}$/;
if (!ANCHOR_RE.test(title)) throw new Error(`fragment needs a valid {{#slug}} anchor: ${title}`); Try / catch
match validate_result {
Err(e) if e.to_string().contains("invalid anchor") => {
eprintln!("fix the fragment title anchor per the message, then re-run");
}
r => r?,
} Prevention
- Run `vdev check changelog-fragments` locally before pushing breaking fragments.
- Use lowercase kebab-case slugs only.
- Add a pre-commit hook that lints changelog.d fragments.
- Copy an existing valid fragment as a template.
When it happens
Trigger: A changelog fragment in changelog.d declares a breaking change whose title lacks an `{{#some-valid-slug}}` suffix, or whose anchor slug violates the shared anchor rules (e.g. illegal characters, empty slug) — detected while running `vdev release generate-cue`.
Common situations: A contributor authored a breaking fragment without reading the anchor convention, or hand-edited the anchor into something like `{{#}}` or `{{#Bad Slug!}}` that passes a casual glance but fails is_valid_anchor.
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
- duplicate upgrade-guide anchor '#
- content between the title and `## Summary` is not allowed —…
- Duplicate deprecation fragments for `what
- exactly one `## Migration` section is required
- exactly one `## Summary` section is required
AI-assisted analysis of vectordotdev/vector@0d4ab78a4f (2026-09-16).
Data as JSON: /api/errors/b062aabf3b17450f.
Report an issue: GitHub.
Appendix: source
Thrown at vdev/src/commands/release/generate_cue.rs:744
return Ok(Some(path));
}
}
Ok(None)
}
fn upgrade_guide_filename(date: &str, version: &Version) -> String {
let version_slug = format!("{}-{}-{}", version.major, version.minor, version.patch);
format!("{date}-{version_slug}-upgrade-guide.md")
}
/// Fail the release if any breaking fragment produced an invalid, empty, or duplicate
/// anchor. Uses the same anchor rules as `vdev check changelog-fragments` (shared through
/// `commands::changelog::is_valid_anchor`) so a fragment that passes CI can't fail here.
fn validate_breaking_anchors(breaking: &[&BreakingDetails]) -> Result<()> {
let mut seen = std::collections::HashMap::<&str, &str>::new();
for b in breaking {
if !crate::commands::changelog::is_valid_anchor(&b.anchor) {
bail!(
"breaking fragment '{}' has an invalid anchor '{}'. Add `{{#some-valid-slug}}` after the title.",
b.title,
b.anchor,
);
}
if let Some(other) = seen.insert(b.anchor.as_str(), b.title.as_str()) {
bail!(
"duplicate upgrade-guide anchor '#{}' shared by breaking fragments '{other}' and '{}'. Override one with `{{#unique-slug}}`.",
b.anchor,
b.title,
);
}
}
Ok(())
}
/// Write `content` to `path` via a `.tmp` sibling then atomic rename. Prevents leaving a
/// partial output behind if the process is killed mid-write.View on GitHub (pinned to 0d4ab78a4f)