{"record":{"id":"b062aabf3b17450f","repo":"vectordotdev/vector","slug":"breaking-fragment-has-an-invalid-anchor-add-some-valid-slug","errorCode":null,"errorMessage":"breaking fragment '{}' has an invalid anchor '{}'. Add `{{#some-valid-slug}}` after the title.","messagePattern":"breaking fragment '(.+?)' has an invalid anchor '(.+?)'\\. Add `(.+?)\\}` after the title\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"vdev/src/commands/release/generate_cue.rs","lineNumber":744,"sourceCode":"            return Ok(Some(path));\n        }\n    }\n    Ok(None)\n}\n\nfn upgrade_guide_filename(date: &str, version: &Version) -> String {\n    let version_slug = format!(\"{}-{}-{}\", version.major, version.minor, version.patch);\n    format!(\"{date}-{version_slug}-upgrade-guide.md\")\n}\n\n/// Fail the release if any breaking fragment produced an invalid, empty, or duplicate\n/// anchor. Uses the same anchor rules as `vdev check changelog-fragments` (shared through\n/// `commands::changelog::is_valid_anchor`) so a fragment that passes CI can't fail here.\nfn validate_breaking_anchors(breaking: &[&BreakingDetails]) -> Result<()> {\n    let mut seen = std::collections::HashMap::<&str, &str>::new();\n    for b in breaking {\n        if !crate::commands::changelog::is_valid_anchor(&b.anchor) {\n            bail!(\n                \"breaking fragment '{}' has an invalid anchor '{}'. Add `{{#some-valid-slug}}` after the title.\",\n                b.title,\n                b.anchor,\n            );\n        }\n        if let Some(other) = seen.insert(b.anchor.as_str(), b.title.as_str()) {\n            bail!(\n                \"duplicate upgrade-guide anchor '#{}' shared by breaking fragments '{other}' and '{}'. Override one with `{{#unique-slug}}`.\",\n                b.anchor,\n                b.title,\n            );\n        }\n    }\n    Ok(())\n}\n\n/// Write `content` to `path` via a `.tmp` sibling then atomic rename. Prevents leaving a\n/// partial output behind if the process is killed mid-write.","sourceCodeStart":726,"sourceCodeEnd":762,"githubUrl":"https://github.com/vectordotdev/vector/blob/0d4ab78a4f0d9c9e5d03a50108a2ae4d2f4b2460/vdev/src/commands/release/generate_cue.rs#L726-L762","documentation":"`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.","triggerScenarios":"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`.","commonSituations":"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.","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`."],"exampleFix":"// before (changelog.d/1234_breaking.md)\n## drop the `metrics` sink {{#}}\n// after\n## drop the `metrics` sink {{#drop-metrics-sink}}","handlingStrategy":"validation","validationCode":"// validate a fragment anchor before committing it\nconst ANCHOR_RE = /\\{\\{#[a-z0-9]+(?:-[a-z0-9]+)*\\}\\}$/;\nif (!ANCHOR_RE.test(title)) throw new Error(`fragment needs a valid {{#slug}} anchor: ${title}`);","typeGuard":null,"tryCatchPattern":"match validate_result {\n    Err(e) if e.to_string().contains(\"invalid anchor\") => {\n        eprintln!(\"fix the fragment title anchor per the message, then re-run\");\n    }\n    r => r?,\n}","preventionTips":["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."],"tags":["changelog","validation","anchor","release-notes"],"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"}