vectordotdev/vector · error
invalid breaking fragment
Error message
invalid breaking fragment '{filename}': title still contains the scaffolder placeholder 'TODO'. What it means
`vdev check changelog-fragments` rejects a breaking fragment whose title still contains the literal placeholder 'TODO' left by the fragment scaffolder. This catches fragments created from the template but never actually filled in.
Solutions
- Replace the TODO placeholder in the title with a real description of the breaking change.
- Re-run `make check-changelog-fragments` locally before pushing.
Example fix
// before ### TODO // after ### "`http` source": removed deprecated `headers` config option
Defensive patterns
Strategy: validation
Validate before calling
let title = /* parsed title */;
if title.contains("TODO") { panic!("fill in the TODO before committing the fragment"); } Type guard
fn title_filled(title: &str) -> bool { !title.is_empty() && !title.contains("TODO") } Prevention
- Treat scaffold TODOs as uncommitted work; never `git add -A` them.
- Review fragment diffs for 'TODO' before opening the PR.
- Use a grep pre-commit hook: `! grep -q TODO <fragment>`.
When it happens
Trigger: A breaking fragment file was generated from the scaffold template and committed with the title still containing 'TODO', e.g. `TODO: describe the change`.
Common situations: Contributor scaffolds a fragment early, forgets to replace the TODO before opening a PR; CI then fails the changelog-fragments check.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- invalid breaking fragment
- invalid breaking fragment
- invalid fragment contents for
- invalid fragment contents for
- invalid fragment contents for
AI-assisted analysis of vectordotdev/vector@bdb87aeaa4 (2026-09-16).
Data as JSON: /api/errors/05f3ea3fb51b9030.
Report an issue: GitHub.
Appendix: source
Thrown at vdev/src/commands/check/changelog_fragments.rs:270
/// <markdown — "Action needed" body for the upgrade guide, or "N/A">
///
/// authors: <name> [<name> ...]
/// ```
fn validate_breaking_fragment(content: &str, filename: &str) -> Result<()> {
// Strip the trailing `authors:` line before parsing — it's not part of the markdown
// structure and would otherwise land inside the Migration section.
let body_before_authors = content
.rsplit_once("\nauthors: ")
.map_or(content, |(before, _)| before);
let sections = parse_breaking_sections(body_before_authors)
.map_err(|e| anyhow::anyhow!("invalid breaking fragment '{filename}': {e}"))?;
if sections.title.is_empty() {
bail!("invalid breaking fragment '{filename}': title must not be empty.");
}
if sections.title.contains("TODO") {
bail!(
"invalid breaking fragment '{filename}': title still contains the scaffolder placeholder 'TODO'."
);
}
if let Some(anchor) = sections.anchor.as_deref()
&& !is_valid_anchor(anchor)
{
bail!(
"invalid breaking fragment '{filename}': anchor must be a lowercase kebab-case slug (a-z, 0-9, hyphens); got '{anchor}'."
);
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use indoc::{formatdoc, indoc};View on GitHub (pinned to bdb87aeaa4)