Missing Credentials
Symptom
The runner container starts but fails its first LLM call with one of:
ERROR provider_key_missing provider=anthropic
ERROR CM_GATEWAY_API_KEY is unset
ERROR authentication_error: invalid_api_key (401)A session-create job may report provider_key_missing directly, or the
launch may reach READY and only fail at first prompt.
Why it happens
Runner sessions inherit credentials from three layers, merged in priority order (highest wins):
- Job-provided env vars — passed via
session.createjob payload (used by templates that override defaults). - Credential vault — fetched by the agent from
GET /gateway/admin/runners/byovm/agents/$AGENT_ID/credentialson session start. - Host environment —
OPENROUTER_API_KEY,ANTHROPIC_API_KEY,OPENAI_API_KEY,DEEPSEEK_API_KEY,GOOGLE_API_KEYfrom the agent process’s own environment.
This error means none of the three layers had the variable the runner asked for.
Fix
Option A — Set it in the credential vault (recommended)
The vault is the right place for production: secrets stay in the dashboard, not on every host, and rotation is one click.
In the dashboard: Runners → Credentials → Add Credential.
The cm-runner agent fetches the vault on every session.create and merges
keys into the container’s env — no agent restart needed.
Option B — Set on the agent host
For dev / single-machine setups, export the variable in the agent’s environment:
docker rm -f cm-runner
docker run -d \
--name cm-runner \
-e ANTHROPIC_API_KEY=sk-ant-... \
-e OPENAI_API_KEY=sk-... \
-e CM_REGISTRATION_TOKEN=$REGISTRATION_TOKEN \
-e CM_GATEWAY_URL=https://api.curate-me.ai \
-v /var/run/docker.sock:/var/run/docker.sock \
ghcr.io/curate-me-ai/cm-runner:latestHost-level env vars are visible to anything else running on that host. Use the credential vault for any shared machine.
Option C — Route LLM calls through the gateway (no provider key in the runner)
For most templates the runner doesn’t need a provider key at all — it just
needs CM_GATEWAY_API_KEY (a Curate-Me gateway key, cm_sk_*) and we proxy
to whatever provider the model alias resolves to.
Set this on the agent host or in the vault:
CM_GATEWAY_API_KEY=cm_sk_your_gateway_key
OPENAI_API_KEY=cm_sk_your_gateway_key # alias for SDKs that read OPENAI_API_KEY
OPENAI_BASE_URL=https://api.curate-me.ai/v1/openaiThis is the path used by all the certified gallery templates — it keeps provider keys out of customer machines entirely.
Verify
Once a credential is set, re-launch the runner. The cm-runner agent log should show:
INFO Merged N vault credentials into session envAnd the session should reach READY without provider_key_missing.
Where to find logs
docker logs cm-runner --tail 200 | grep -E "credentials|provider_key|vault"Server-side: byovm_credentials_fetched (success) or byovm_credentials_fetch_failed.
Related
- OpenClaw Boot Failed — broader failure category for first-prompt failures
- Gateway Integration overview — how the proxy auth flow works