{"record":{"id":"ddf53a3683910d63","repo":"aaif-goose/goose","slug":"missing-env-vars-for-provider-provider","errorCode":null,"errorMessage":"Missing env vars for provider '{provider}': {', '.join(missing_secrets)}. Set them in a .env file (cwd or {HARBOR_DIR}) or your shell.","messagePattern":"Missing env vars for provider '(.+?)': (.+?)\\. Set them in a \\.env file \\(cwd or (.+?)\\) or your shell\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"evals/harbor/runner.py","lineNumber":147,"sourceCode":"    if args.trials < 1:\n        raise ValueError(\"--trials must be at least 1\")\n    if args.concurrency < 1:\n        raise ValueError(\"--concurrency must be at least 1\")\n    if args.timeout_multiplier <= 0:\n        raise ValueError(\"--timeout-multiplier must be positive\")\n\n    goose_binary = args.goose_binary.expanduser().resolve()\n    if not goose_binary.is_file():\n        raise ValueError(f\"--goose-binary does not exist or is not a file: {args.goose_binary}\")\n\n    config_yaml, extension_entries = render_goose_config(args.extensions)\n\n    provider = args.model.split(\"/\", 1)[0]\n    missing_secrets = [\n        key for key in PROVIDER_SECRETS.get(provider, []) if not os.environ.get(key)\n    ]\n    if missing_secrets:\n        raise ValueError(\n            f\"Missing env vars for provider '{provider}': {', '.join(missing_secrets)}. \"\n            f\"Set them in a .env file (cwd or {HARBOR_DIR}) or your shell.\"\n        )\n\n    agent_kwargs: dict[str, Any] = {\n        \"goose_binary\": str(goose_binary),\n        \"config_yaml\": config_yaml,\n        \"extension_entries\": extension_entries,\n        \"install_goose_runtime_deps\": args.install_goose_runtime_deps,\n    }\n    if args.max_turns is not None:\n        agent_kwargs[\"max_turns\"] = args.max_turns\n\n    job_name = (\n        validate_job_name(args.job_name)\n        if args.job_name\n        else default_job_name(args.model, args.dataset)\n    )","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/aaif-goose/goose/blob/3810898a7447ec3299be72e223d3570a7aabf0ab/evals/harbor/runner.py#L129-L165","documentation":"Raised by build_harbor_config in the harbor benchmark runner after it splits --model into a provider prefix and looks that provider up in PROVIDER_SECRETS (imported from agent.py). Every listed environment variable (typically the provider API key) must already exist and be non-empty in os.environ; load_dotenv only fills vars from a .env file in the cwd or in evals/harbor/, and only ones not already set. The message names the provider, the exact missing keys, and both .env locations.","triggerScenarios":"Running with --model anthropic/claude-sonnet-4-6 without ANTHROPIC_API_KEY in the environment or either .env file; a .env that exists but misspells the key name; exporting the variable as an empty string (os.environ.get returns '' which counts as missing); using a provider prefix whose secrets map entry differs (e.g. a bare model provider alias).","commonSituations":"CI shells that start clean without sourcing the developer's env; .env placed in a directory other than cwd or evals/harbor/; rotating keys and forgetting to update .env; assuming the desktop app's stored key is visible to the eval runner.","solutions":["Put the named keys in a .env file in the cwd or in evals/harbor/ (KEY=value lines), or export them in the shell","Copy the exact key names from the error message; check spelling and that values are non-empty","Confirm the provider prefix in --model is the one PROVIDER_SECRETS expects (anthropic/, openai/, ...)"],"exampleFix":"# before\n# no .env anywhere; keys only in the desktop app\npython runner.py --model anthropic/claude-sonnet-4-6\n\n# after\nprintf 'ANTHROPIC_API_KEY=<your-key-here>\\n' > evals/harbor/.env\npython runner.py --model anthropic/claude-sonnet-4-6","handlingStrategy":"validation","validationCode":"import os\nfrom agent import PROVIDER_SECRETS\n\nprovider = args.model.split('/', 1)[0]\nmissing = [k for k in PROVIDER_SECRETS.get(provider, []) if not os.environ.get(k)]\nassert not missing, (\n    f'missing env vars: {missing}. '\n    'Put them in ./.env or evals/harbor/.env, or export them'\n)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep a .env in evals/harbor/ with the provider keys you benchmark (reference keys by name only)","Check exported values are non-empty — empty strings count as missing","Recheck after switching --model providers; each provider has its own key set"],"tags":["environment","secrets","provider","harbor","benchmark","dotenv"],"backgroundTag":null,"analyzedSha":"3810898a7447ec3299be72e223d3570a7aabf0ab","analyzedAt":"2026-08-16T10:14:26.282Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}