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
- Build first (cargo build or just release-binary), then pass an absolute path: --goose-binary /abs/path/to/repo/target/release/goose
- Resolve the real location with 'command -v goose' or 'ls target/release/goose' and use that exact path
- 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
- Build the binary before running evals
- Pass absolute paths; resolve relative ones against the repo root in wrapper scripts
- Verify with 'command -v goose' when using an installed binary
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
- Job name must start with a letter or number and contain only
- --model must be in provider/model form, e.g. anthropic/claud
- --trials must be at least 1
- --concurrency must be at least 1
- --timeout-multiplier must be positive
AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16).
Data as JSON: /api/errors/fbb872311a6466c1.
Report an issue: GitHub.