vectordotdev/vector · error

Malformed git log entry

Error message

Malformed git log entry `{line}`

What it means

parse_pull_request_history splits each non-empty git log line into (commit, title) on a single TAB character. Any line lacking a TAB — i.e. output that doesn't match the expected `git log --format='%H %s'` layout — triggers this error, indicating corrupted or hand-modified git log output.

Solutions

  1. Run the release command in a clean environment without git config overrides affecting log format (unset GIT_ALIASES / format overrides, disable pagers: `git config --global core.pager cat`).
  2. Verify `git log --format='%H%x09%s'` output for the fragment's commits contains one TAB per line.
  3. Re-run the release command; if a specific commit's subject embeds a TAB, amend the commit message to remove it.

Example fix

// before
[alias]
  log = log --graph --oneline   # rewrites all log output
// after
# remove the alias or run vdev with overridden config
git -c alias.log=log release prepare ...
Defensive patterns

Strategy: type-guard

Validate before calling

let out = std::process::Command::new("git")
    .args(["log", "--format=%H%x09%s"])
    .output().unwrap();
assert!(out.stdout.lines().all(|l| l.contains('\t')), "unexpected git log format");

Type guard

fn is_wellformed_log_line(line: &str) -> bool { line.split_once('\t').is_some() }

Prevention

When it happens

Trigger: lookup_pull_requests_from_git runs git log over commits touching a fragment; a returned line has no '\t' separator, e.g. because a custom git log format, git alias, or pager rewrote the output.

Common situations: A user has a global git config (e.g. format.pretty override via alias or pager filter) altering log output; running the tool in an environment where GIT_* env vars change log formatting; truncated log output piped through another tool.

Understand the failure class

Related errors


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

Appendix: source

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

    parse_pull_request_history(&commit_history, latest_addition, pull_request_metadata)
        .with_context(|| {
            format!("Could not determine every PR that added or edited {relative_path}")
        })
}

fn parse_pull_request_history(
    commit_history: &str,
    latest_addition: &str,
    pull_request_metadata: PullRequestMetadata,
) -> Result<Vec<u64>> {
    let mut numbers = Vec::new();
    for line in commit_history
        .lines()
        .filter(|line| !line.trim().is_empty())
    {
        let (commit, title) = line
            .split_once('\t')
            .ok_or_else(|| anyhow!("Malformed git log entry `{line}`"))?;

        match parse_pull_request_number(title) {
            Ok(number) if !numbers.contains(&number) => numbers.push(number),
            Ok(_) => {}
            Err(_) if pull_request_metadata == PullRequestMetadata::Optional => {}
            Err(error) => return Err(error.context(format!("Commit {commit}: `{title}`"))),
        }

        if commit == latest_addition {
            return Ok(numbers);
        }
    }

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

View on GitHub (pinned to 0d4ab78a4f)