dbt-labs/dbt-core · error
--commit-author and --commit-email must be set together
Error message
--commit-author and --commit-email must be set together
What it means
When committing the formula update to the tap repository, the commit author identity can optionally be overridden via `--commit-author` and `--commit-email`. `run` enforces that these two options are always supplied together: providing exactly one leaves git's user config half-specified, so the command bails with a descriptive message. Providing neither is allowed, in which case the inherited git identity is used.
Source
Thrown at crates/dbt-ci/src/homebrew/publish.rs:97
fs::copy(&args.formula, &dest)
.with_context(|| format!("copy {} -> {}", args.formula.display(), dest.display()))?;
let status = run_git_capture(Some(work.path()), &["status", "--porcelain"])?;
if status.trim().is_empty() {
eprintln!("✓ {} already up to date in tap", filename);
return Ok(());
}
// Only override identity if BOTH flags are provided. Otherwise inherit
// whatever git config the cloned tap has — which on a dev machine comes
// from `~/.gitconfig`.
match (&args.commit_author, &args.commit_email) {
(Some(name), Some(email)) => {
run_git(Some(work.path()), &["config", "user.name", name])?;
run_git(Some(work.path()), &["config", "user.email", email])?;
}
(None, None) => {} // inherit
_ => bail!("--commit-author and --commit-email must be set together"),
}
run_git(Some(work.path()), &["add", &format!("Formula/{filename}")])?;
let message = format!(
"{stem} {version}",
stem = filename.trim_end_matches(".rb"),
version = args.version,
);
run_git(Some(work.path()), &["commit", "-m", &message])?;
if args.dry_run {
eprintln!("→ dry-run: skipping push. Patch follows:\n");
run_git(Some(work.path()), &["--no-pager", "show", "HEAD"])?;
return Ok(());
}
// Push needs the same `-c http.extraHeader=…` knobs as clone.
let mut push_argv: Vec<OsString> = auth_args;View on GitHub (pinned to 0267ce9170)
Solutions
- Pass both flags together: `--commit-author "Bot Name" --commit-email bot@example.com`.
- If you want the default git identity, remove both flags and let the tap repo's configured user.name/user.email apply.
- Fix the CI template/workflow so both values are sourced together (e.g., from the same bot identity config).
Example fix
// before dbt-ci homebrew publish --formula Formula/dbt.rb --commit-author "Release Bot" // after dbt-ci homebrew publish --formula Formula/dbt.rb --commit-author "Release Bot" --commit-email bot@example.com
Defensive patterns
Strategy: validation
Validate before calling
fn validate_commit_identity(author: &Option<String>, email: &Option<String>) -> Result<(), String> {
match (author, email) {
(Some(_), Some(_)) | (None, None) => Ok(()),
_ => Err("--commit-author and --commit-email must be set together".to_string()),
}
} Try / catch
match publish(args) {
Err(e) if e.to_string().contains("must be set together") => {
eprintln!("Supply both --commit-author and --commit-email, or neither.");
std::process::exit(2);
}
Err(e) => return Err(e),
Ok(v) => Ok(v),
} Prevention
- Define the bot identity (name + email) as a single unit in CI config so both flags are always templated together.
- Wrap the publish invocation in a wrapper script that enforces the pair before calling the CLI.
- Default to omitting both flags and relying on the tap repo's configured git identity when unsure.
When it happens
Trigger: Running `dbt-ci homebrew publish` with `--commit-author <name>` but no `--commit-email`, or `--commit-email <email>` but no `--commit-author`.
Common situations: CI templating that fills one variable but not the other (e.g., a secrets/config map containing the bot name but not the email); a developer hand-typing the flags and forgetting the pair; scripts updated to add an author override without updating the email.
Understand the failure class
Background: "mutually exclusive" flag errors: what "can't supply both nx and xx", "--raw is not compatible with -i" and "cannot be used with" mean, and how to fix them — this error's family across 29 libraries.
Related errors
- formula file not found: {}
- formula filename does not end in .rb: {filename}
- --download-base-url requires at least one --target
- `git {}` exited with status {}
- SemVer build metadata not supported in {semver:?}
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/b795d5b30996c9ce.
Report an issue: GitHub.