vectordotdev/vector · error

Commit title must end with

Error message

Commit title must end with `(#<PR number>)`

What it means

The release tooling requires every commit title on a release branch to end with a PR reference in the form `(#<digits>)`, so PR metadata can be recovered from history. This error fires when a commit title does not match that pattern (no trailing '(#N)'), unless PullRequestMetadata::Optional is configured.

Solutions

  1. Amend or rebase the offending commit so its title ends with `(#<PR number>)` (e.g. `git commit --amend -m "fix: thing (#12345)"`).
  2. If PR metadata is intentionally absent for some commits, use the Optional PullRequestMetadata mode in the release command.
  3. Identify the commit via the context line added by the error ("Commit <sha>: `<title>`") and fix it first, then re-run.

Example fix

// before
git commit --amend -m "fix: correct TLS handshake"
// after
git commit --amend -m "fix: correct TLS handshake (#12345)"
Defensive patterns

Strategy: validation

Validate before calling

let title_ok = |t: &str| {
    t.trim().strip_suffix(')')
        .and_then(|t| t.rsplit_once("(#"))
        .map(|(_, n)| !n.is_empty() && n.bytes().all(|b| b.is_ascii_digit()))
        .unwrap_or(false)
};
// check every commit title on the release branch before preparing a release

Prevention

When it happens

Trigger: parse_pull_request_history processes a commit whose title lacks a trailing `(#123)`; this propagates up from lookup_pull_requests during release CUE generation when pull request metadata is required.

Common situations: A maintainer squash-merged a PR with the '(#N)' suffix stripped by a custom merge-commit template; a direct push to the release branch bypassing PRs; a PR title manually edited to drop the number.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


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

Appendix: source

Thrown at vdev/src/commands/release/generate_cue.rs:519

        }
    }

    match pull_request_metadata {
        PullRequestMetadata::Optional => Ok(Vec::new()),
        PullRequestMetadata::Required => {
            bail!("Could not find latest addition commit {latest_addition} in the fragment history")
        }
    }
}

fn parse_pull_request_number(commit_title: &str) -> Result<u64> {
    let number = commit_title
        .trim()
        .strip_suffix(')')
        .and_then(|title| title.rsplit_once("(#"))
        .map(|(_, number)| number)
        .filter(|number| !number.is_empty() && number.bytes().all(|byte| byte.is_ascii_digit()))
        .ok_or_else(|| anyhow!("Commit title must end with `(#<PR number>)`"))?;

    number
        .parse()
        .with_context(|| format!("Invalid PR number in commit title `{commit_title}`"))
}

#[cfg(not(test))]
fn ensure_full_git_history(repo_root: &Path) -> Result<()> {
    let is_shallow = run_command("git", &["rev-parse", "--is-shallow-repository"], repo_root)?;
    if is_shallow.trim() == "true" {
        bail!(
            "Release generation requires full Git history to find the PRs that introduced changelog fragments."
        );
    }
    Ok(())
}

#[cfg(test)]

View on GitHub (pinned to 0d4ab78a4f)