dbt-labs/dbt-core · error

formula filename does not end in .rb: {filename}

Error message

formula filename does not end in .rb: {filename}

What it means

After extracting the formula's filename, `run` checks that it ends with the `.rb` extension required by Homebrew formulas. If the filename has any other extension (or none), the command aborts with `bail!`. Homebrew taps store formulas as Ruby files under `Formula/`, so a non-`.rb` file cannot be published.

Source

Thrown at crates/dbt-ci/src/homebrew/publish.rs:52

            ExitCode::from(2)
        }
    }
}

fn run(args: HomebrewPublishArgs) -> Result<()> {
    validate_release_version(&args.version)
        .with_context(|| format!("invalid --version {:?}", args.version))?;
    if !args.formula.is_file() {
        bail!("formula file not found: {}", args.formula.display());
    }
    let filename = args
        .formula
        .file_name()
        .and_then(|s| s.to_str())
        .ok_or_else(|| anyhow!("formula path has no filename: {}", args.formula.display()))?
        .to_string();
    if !filename.ends_with(".rb") {
        bail!("formula filename does not end in .rb: {filename}");
    }

    let token = read_token(&args.token_env, args.dry_run)?;
    // For HTTPS tap URLs, build an `http.extraHeader` config knob carrying
    // Basic auth credentials. Non-HTTPS URLs (file://, ssh) carry their
    // own auth.
    let auth_args = build_auth_args(&args.tap_repo, token.as_deref());

    let work = TempDir::new("dbt-ci-brew-publish")?;
    eprintln!("→ git clone {} -> {}", args.tap_repo, work.path().display());
    let mut clone_argv: Vec<OsString> = auth_args.clone();
    clone_argv.push("clone".into());
    if !is_local_path(&args.tap_repo) {
        clone_argv.push("--depth".into());
        clone_argv.push("1".into());
    }
    clone_argv.push("-b".into());
    clone_argv.push((&args.tap_branch).into());

View on GitHub (pinned to 0267ce9170)

Solutions

  1. Point `--formula` at the actual Ruby formula file ending in `.rb` (e.g., `Formula/dbt.rb`).
  2. If the file is misnamed, rename it to include the `.rb` extension before publishing.
  3. If you are publishing a release artifact, this is the wrong input; publish the formula file, not the artifact.

Example fix

// before
dbt-ci homebrew publish --formula ./dist/dbt-cli-linux.tar.gz
// after
dbt-ci homebrew publish --formula ./Formula/dbt.rb
Defensive patterns

Strategy: validation

Validate before calling

use std::path::Path;
fn validate_formula_extension(p: &Path) -> Result<(), String> {
    let name = p.file_name().and_then(|s| s.to_str()).ok_or("path has no filename")?;
    if !name.ends_with(".rb") {
        return Err(format!("formula filename does not end in .rb: {name}"));
    }
    Ok(())
}

Try / catch

if let Err(e) = publish(args) {
    if e.to_string().contains("does not end in .rb") {
        eprintln!("--formula must point at a Homebrew .rb formula file, got: {}", args.formula.display());
        std::process::exit(2);
    }
    return Err(e);
}

Prevention

When it happens

Trigger: Running `dbt-ci homebrew publish` with a `--formula` path whose final filename component does not end in `.rb`, e.g. `--formula dist/dbt.txt`, `--formula ./formula`, or `--formula dbt`.

Common situations: Passing a release artifact (tarball, binary) instead of the formula file; a formula file that was renamed without the `.rb` extension; shell completion or scripting picking up the wrong file.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07). Data as JSON: /api/errors/3e36633ba3bb83cb. Report an issue: GitHub.