aaif-goose/goose · error · ValueError

--goose-binary does not exist or is not a file: {args.goose_

Error message

--goose-binary does not exist or is not a file: {args.goose_binary}

What it means

Raised by build_harbor_config in the harbor benchmark runner when the --goose-binary path, after expanduser().resolve(), is not a regular file. The agent executes this binary to run each trial, so a missing binary means every task would fail at spawn time; the runner checks the path up front and names the offending path in the message. Directories, dangling symlinks, and never-built targets all fail the is_file() check.

Source

Thrown at evals/harbor/runner.py:138

        dataset["ref" if "/" in name else "version"] = ref
    if tasks:
        dataset["task_names"] = tasks
    return dataset


def build_harbor_config(args: argparse.Namespace) -> dict[str, Any]:
    if "/" not in args.model:
        raise ValueError("--model must be in provider/model form, e.g. anthropic/claude-sonnet-4-6")
    if args.trials < 1:
        raise ValueError("--trials must be at least 1")
    if args.concurrency < 1:
        raise ValueError("--concurrency must be at least 1")
    if args.timeout_multiplier <= 0:
        raise ValueError("--timeout-multiplier must be positive")

    goose_binary = args.goose_binary.expanduser().resolve()
    if not goose_binary.is_file():
        raise ValueError(f"--goose-binary does not exist or is not a file: {args.goose_binary}")

    config_yaml, extension_entries = render_goose_config(args.extensions)

    provider = args.model.split("/", 1)[0]
    missing_secrets = [
        key for key in PROVIDER_SECRETS.get(provider, []) if not os.environ.get(key)
    ]
    if missing_secrets:
        raise ValueError(
            f"Missing env vars for provider '{provider}': {', '.join(missing_secrets)}. "
            f"Set them in a .env file (cwd or {HARBOR_DIR}) or your shell."
        )

    agent_kwargs: dict[str, Any] = {
        "goose_binary": str(goose_binary),
        "config_yaml": config_yaml,
        "extension_entries": extension_entries,
        "install_goose_runtime_deps": args.install_goose_runtime_deps,

View on GitHub (pinned to 3810898a74)

Solutions

  1. Build first (cargo build or just release-binary), then pass an absolute path: --goose-binary /abs/path/to/repo/target/release/goose
  2. Resolve the real location with 'command -v goose' or 'ls target/release/goose' and use that exact path
  3. Confirm the path is a file, not the containing directory

Example fix

# before
python runner.py --goose-binary ./target/debug/goose   # run from the wrong cwd

# after
cargo build
python runner.py --goose-binary "$(pwd)/target/debug/goose"
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path

goose = Path(args.goose_binary).expanduser().resolve()
assert goose.is_file(), (
    f'build goose first (cargo build), then pass --goose-binary {goose}'
)

Prevention

When it happens

Trigger: Passing a relative path like ./target/debug/goose from a different working directory; passing the target directory instead of the binary; binary not built yet (cargo build never run); ~ shorthand for the wrong user.

Common situations: Fresh clones that skipped cargo build; running the eval from a different cwd than the repo root with relative paths; pointing at a release path after only a debug build (or vice versa); moving/renaming the built binary.

Related errors


AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16). Data as JSON: /api/errors/fbb872311a6466c1. Report an issue: GitHub.