vectordotdev/vector · error

No ## headers found in VRL CHANGELOG.md

Error message

No ## headers found in VRL CHANGELOG.md

What it means

After fetching the VRL CHANGELOG.md, `get_vrl_changelog` extracts the first release section by scanning lines from the first `## ` heading to the next one. If the document contains no `##` headers at all, it bails because no release section can be extracted. This indicates an unexpected CHANGELOG.md shape upstream.

Solutions

  1. Inspect the fetched CHANGELOG.md content (curl the raw URL or re-run the gh api command) to see what was actually returned.
  2. Verify the VRL repo/tag arguments point at a real release with a populated changelog.
  3. If the upstream format changed, update get_vrl_changelog's heading parsing (`## `) to match the new format.
  4. If the changelog is legitimately empty for the target release, skip the VRL appendix rather than relying on get_vrl_changelog.

Example fix

// before: stub changelog with only a top-level title
# Changelog
(empty)
// after: ensure the upstream file has release sections
# Changelog

## [0.12.0] - 2026-09-01

- Added ...
Defensive patterns

Strategy: fallback

Validate before calling

# confirm the upstream changelog has release sections before prepare
curl -s https://raw.githubusercontent.com/vectordotdev/vrl/master/CHANGELOG.md | grep -m1 '^## ' || echo "no ## sections found"

Try / catch

if let Err(e) = get_vrl_changelog(...) {
    if e.to_string().contains("No ## headers found") {
        eprintln!("VRL changelog has no release sections; verify upstream content or skip the VRL appendix");
    }
}

Prevention

When it happens

Trigger: The VRL CHANGELOG.md fetched via `gh api` during append_vrl_changelog_to_release_cue contains zero lines starting with `## ` — e.g. the file is empty, an error page/JSON body was captured, or the upstream changelog format changed.

Common situations: A newly-minted VRL repo whose CHANGELOG.md is a stub without release sections, a gh API call that returned an error payload with exit code 0, or an upstream reformat that switched to `#`/`###` headings.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


AI-assisted analysis of vectordotdev/vector@0d4ab78a4f (2026-09-16). Data as JSON: /api/errors/e9b7bee37ea018e4. Report an issue: GitHub.

Appendix: source

Thrown at vdev/src/commands/release/prepare.rs:384

        String::from_utf8(changelog_output.stdout).context("CHANGELOG.md is not valid UTF-8")?;

    // Extract the first release section (from the first ## to the next ##)
    let mut section = Vec::new();
    let mut found_first = false;
    for line in changelog.lines() {
        if line.starts_with("## ") {
            if found_first {
                break;
            }
            found_first = true;
        }
        if found_first {
            section.push(line);
        }
    }

    if !found_first {
        bail!("No ## headers found in VRL CHANGELOG.md");
    }

    Ok(section.join("\n"))
}

#[cfg(test)]
mod tests {
    use crate::commands::release::prepare::{
        format_vrl_changelog_block, insert_block_after_changelog, update_vector_package_version,
        update_vrl_to_version,
    };
    use indoc::indoc;

    #[test]
    fn test_update_vrl_to_version() {
        let input = indoc! {r#"
            [workspace.dependencies]
            some-other-dep = "1.0.0"

View on GitHub (pinned to 0d4ab78a4f)