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

  1. Open the fragment named in the message and add or fix the `{{#valid-slug}}` after the title.
  2. Use lowercase kebab-case slugs (letters, digits, hyphens) matching the rules in commands::changelog::is_valid_anchor.
  3. Run `vdev check changelog-fragments` locally to validate anchors with the same rules before regenerating.
  4. 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

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


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)