JuliusBrussee/caveman · error
openclaw fresh config cannot route through Caveman without $
Error message
openclaw fresh config cannot route through Caveman without ${requiredKey} What it means
freshOpenClawModelRef builds a fresh (non-migrated) openclaw model reference routed through Caveman. In managed mode it requires env var CAVE_API_KEY; otherwise OPENAI_API_KEY. firstEnvSecret checks the variable exists and has non-whitespace content; missing/blank means the request cannot authenticate upstream, so config generation fails fast.
Source
Thrown at packages/cli/src/index.ts:5494
}
function openClawDefaultApiKey(providerId: string): string | undefined {
return openClawSecretString(OPENCLAW_WELL_KNOWN_PROVIDERS[providerId]?.apiKey);
}
function openClawProviderApiKey(providerId: string, provider: JsonObject): string | undefined {
return openClawSecretString(provider.apiKey) ?? openClawDefaultApiKey(providerId);
}
function openClawResolvedProviderApiKey(providerId: string, provider: JsonObject): string | undefined {
const key = openClawProviderApiKey(providerId, provider);
return key ? resolveEnvTemplate(key) : undefined;
}
function freshOpenClawModelRef(ctx: OverlayBuilderContext): OpenClawModelRef {
const requiredKey = ctx.mode === "managed" ? "CAVE_API_KEY" : "OPENAI_API_KEY";
if (!firstEnvSecret(ctx.env, [requiredKey])) {
throw new Error(`openclaw fresh config cannot route through Caveman without ${requiredKey}`);
}
return { provider: "openai", model: OPENCLAW_FRESH_MODEL, raw: `openai/${OPENCLAW_FRESH_MODEL}` };
}
function appendUrlPath(base: string, path: string): string {
return `${base.replace(/\/+$/, "")}${path}`;
}
function codexHomeDir(): string {
return join(homedir(), ".codex");
}
function codexAuthPath(): string {
return join(codexHomeDir(), "auth.json");
}
function nonEmptyString(v: unknown): v is string {
return typeof v === "string" && v.trim().length > 0;View on GitHub (pinned to 27d5a3981a)
Solutions
- Export the required key: `export CAVE_API_KEY=...` (managed) or `export OPENAI_API_KEY=...` (self-hosted) and regenerate
- If using a .env loader, ensure it runs before openclaw config generation
- Provision the secret in CI/secret manager for managed deployments
- Verify with `printenv CAVE_API_KEY` / `printenv OPENAI_API_KEY` that the value is set and non-blank
Example fix
# before openclaw config # Error: cannot route through Caveman without CAVE_API_KEY # after export CAVE_API_KEY="$(devkey run cave-api-key -- echo $CAVE_API_KEY)" # or source from secret store openclaw config
Defensive patterns
Strategy: validation
Validate before calling
const requiredKey = mode === "managed" ? "CAVE_API_KEY" : "OPENAI_API_KEY";
const value = process.env[requiredKey];
if (typeof value !== "string" || value.trim() === "") {
throw new Error(`set ${requiredKey} before generating openclaw config`);
} Type guard
function hasEnvSecret(env: NodeJS.ProcessEnv, key: string): env is Record<string, string> & Record<typeof key, string> {
const v = env[key];
return typeof v === "string" && v.trim().length > 0;
} Try / catch
try {
const ref = freshOpenClawModelRef(ctx);
} catch (error) {
if (/cannot route through Caveman without/.test((error as Error).message)) {
throw new Error(`missing credential: load it via devkey/secret manager, then retry`, { cause: error });
}
throw error;
} Prevention
- Reference credentials by name through a secret loader (devkey) instead of relying on ambient shell env
- Assert required env keys at process start, not deep in config generation
- In CI, fail the job early on missing CAVE_API_KEY/OPENAI_API_KEY with a clear message
When it happens
Trigger: Generating a fresh openclaw config (managed mode → no CAVE_API_KEY; self-hosted mode → no OPENAI_API_KEY) in the environment passed as ctx.env. Only presence of a trimmed non-empty string is checked, not validity.
Common situations: Running openclaw config generation in a shell/CI without exporting the key; key present only in a .env file that is not loaded; managed-mode deployment forgetting to provision CAVE_API_KEY; whitespace-only value.
Related errors
- cave_harness_aborted
- cave_vercel_terminal_failure
- probe returned false
- empty version output
- register requires CAVE_CONTROL_URL, CAVE_TOKEN, and CAVE_PRO
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/5b31b82bd079a6b0.
Report an issue: GitHub.