April 27, 2026 β€’ Version: 2026.3.8

Auth Profiles Not Distributed to Non-Default Agents During Onboard

The `openclaw onboard` command writes authentication credentials only to the default agent directory, leaving all other configured agents without valid auth tokens and causing silent fallback to free models.

πŸ” Symptoms

Direct Observation

When openclaw onboard completes, auth tokens are written to only one directory:

bash $ ls ~/.openclaw/agents/*/agent/auth-profiles.json /home/user/.openclaw/agents/main/agent/auth-profiles.json # exists with valid tokenRef /home/user/.openclaw/agents/chief/agent/auth-profiles.json # MISSING or stale /home/user/.openclaw/agents/developer/agent/auth-profiles.json # MISSING or stale /home/user/.openclaw/agents/qa/agent/auth-profiles.json # MISSING or stale /home/user/.openclaw/agents/secretary/agent/auth-profiles.json # MISSING or stale /home/user/.openclaw/agents/lawyer/agent/auth-profiles.json # MISSING or stale /home/user/.openclaw/agents/writer/agent/auth-profiles.json # MISSING (uses free model) /home/user/.openclaw/agents/experimenter/agent/auth-profiles.json # MISSING or stale

Behavioral Manifestation

Non-default agents silently fall back to free/fallback models without warning:

bash $ openclaw run –agent developer “explain quantum entanglement”

Actual: Routes to GLM 4.5 Air (free fallback), no error shown

Expected: Uses claude-sonnet-4-6 with Anthropic auth

$ cat ~/.openclaw/agents/developer/logs/gateway.log [2026-03-08T14:32:11Z] WARN: No valid auth-profiles.json found for agent ‘developer’, using free fallback model ‘openrouter/z-ai/glm-4.5-air:free’

Exit Code Behavior

Onboard completes successfully (exit code 0) even when other agents lack auth:

bash $ openclaw onboard βœ“ Authenticated with Anthropic (setup-token) βœ“ Token written to agents/main/agent/auth-profiles.json βœ“ Onboarding complete

$ echo $? 0

Agents attempting to use paid models receive no immediate error:

bash $ openclaw run –agent developer “test” 2>&1

Returns results from fallback model, silently

🧠 Root Cause

Code Path Analysis

The onboard command iterates over agents.list in openclaw.json but only writes auth to the path derived from the default agent ID (main), not from each agent’s actual id:

javascript // Source: src/commands/onboard.ts (approximate logic) async function writeAuthProfiles(agents: Agent[], tokenRef: string) { for (const agent of agents) { // BUG: Always uses ‘main’ instead of agent.id const authPath = path.join( process.env.OPENCLAW_HOME || ‘~/.openclaw’, ‘agents’, ‘main’, // ← Hardcoded default agent ID ‘agent’, ‘auth-profiles.json’ );

await fs.writeFile(authPath, JSON.stringify({ tokenRef }));
// Should be: agent.id instead of 'main'

} }

Failure Sequence

  1. User runs openclaw onboard with 7 agents configured
  2. Auth handler validates token against Anthropic API
  3. Token reference is stored in memory
  4. Loop writes auth file 7 times to the same path: ~/.openclaw/agents/main/agent/auth-profiles.json
  5. Final state: Only main agent has auth; all other agent directories retain stale tokens or have no auth file
  6. Gateway starts with main agent properly authenticated
  7. Other agents attempt model calls β†’ gateway checks agents/{id}/agent/auth-profiles.json β†’ not found β†’ silently uses fallback

Architectural Inconsistency

The gateway’s auth resolution follows this priority chain:

  1. Check: agents/{current_agent}/agent/auth-profiles.json
  2. Fallback: Use free/fallback model (no auth required)
  3. Skip: Never checks agents/main/agent/auth-profiles.json as canonical fallback

This differs from how other agent-scoped configs (prompts, tools, context) are inherited from main when agent-specific versions are absent.

Environment Variable Impact

The OPENCLAW_HOME environment variable is respected for the base path, but the agent subdirectory bug remains:

bash $ OPENCLAW_HOME=/opt/openclaw openclaw onboard

Still writes only to /opt/openclaw/agents/main/agent/auth-profiles.json

πŸ› οΈ Step-by-Step Fix

File: src/commands/onboard.ts

Before: typescript for (const agent of agents) { const authDir = path.join( openclawHome, ‘agents’, ‘main’, // BUG: hardcoded ‘agent’ ); await fs.mkdir(authDir, { recursive: true }); await fs.writeFile( path.join(authDir, ‘auth-profiles.json’), JSON.stringify({ tokenRef: validatedToken.tokenRef }, null, 2) ); }

After: typescript for (const agent of agents) { const authDir = path.join( openclawHome, ‘agents’, agent.id, // FIX: use actual agent ID ‘agent’ ); await fs.mkdir(authDir, { recursive: true }); await fs.writeFile( path.join(authDir, ‘auth-profiles.json’), JSON.stringify({ tokenRef: validatedToken.tokenRef }, null, 2) ); }

Rebuild and reinstall: bash cd openclaw npm run build npm link openclaw onboard –reauth # re-authenticate with new fix


Option B: Gateway Fallback Auth Resolution (Alternative)

Modify src/gateway/auth-resolver.ts to inherit from main agent:

Before: typescript async resolveAuth(agentId: string): Promise<AuthProfile | null> { const agentAuthPath = path.join(openclawHome, ‘agents’, agentId, ‘agent’, ‘auth-profiles.json’);

if (fs.existsSync(agentAuthPath)) { return this.loadAuthProfile(agentAuthPath); }

return null; // Falls through to free model }

After: typescript async resolveAuth(agentId: string): Promise<AuthProfile | null> { // Check agent-specific auth first const agentAuthPath = path.join(openclawHome, ‘agents’, agentId, ‘agent’, ‘auth-profiles.json’);

if (fs.existsSync(agentAuthPath)) { return this.loadAuthProfile(agentAuthPath); }

// Fallback: inherit from default agent (main) if agent-specific is missing if (agentId !== ‘main’) { const defaultAuthPath = path.join(openclawHome, ‘agents’, ‘main’, ‘agent’, ‘auth-profiles.json’); if (fs.existsSync(defaultAuthPath)) { console.warn([Auth] Agent '${agentId}' has no auth file; inheriting from 'main'. Run 'openclaw onboard' to provision explicitly.); return this.loadAuthProfile(defaultAuthPath); } }

return null; }


Temporary Workaround (Immediate)

bash

Define agents from your config

AGENTS=“main chief developer qa secretary lawyer writer experimenter”

Create directories and copy auth

for agent in $AGENTS; do mkdir -p ~/.openclaw/agents/$agent/agent cp ~/.openclaw/agents/main/agent/auth-profiles.json
~/.openclaw/agents/$agent/agent/auth-profiles.json done

Restart gateway to pick up new tokens

pkill -f “openclaw gateway” openclaw gateway start &

Single-command version: bash jq -r ‘.agents.list[].id’ openclaw.json | xargs -I{} sh -c ‘mkdir -p ~/.openclaw/agents/{}/agent && cp ~/.openclaw/agents/main/agent/auth-profiles.json ~/.openclaw/agents/{}/agent/’

πŸ§ͺ Verification

1. Confirm All Auth Files Exist

bash $ ls -la ~/.openclaw/agents/*/agent/auth-profiles.json -rw——- 1 user user 892 Mar 8 14:30 /home/user/.openclaw/agents/chief/agent/auth-profiles.json -rw——- 1 user user 892 Mar 8 14:30 /home/user/.openclaw/agents/developer/agent/auth-profiles.json -rw——- 1 user user 892 Mar 8 14:30 /home/user/.openclaw/agents/main/agent/auth-profiles.json -rw——- 1 user user 892 Mar 8 14:30 /home/user/.openclaw/agents/experimenter/agent/auth-profiles.json -rw——- 1 user user 892 Mar 8 14:30 /home/user/.openclaw/agents/lawyer/agent/auth-profiles.json -rw——- 1 user user 892 Mar 8 14:30 /home/user/.openclaw/agents/qa/agent/auth-profiles.json -rw——- 1 user user 892 Mar 8 14:30 /home/user/.openclaw/agents/secretary/agent/auth-profiles.json -rw——- 1 user user 892 Mar 8 14:30 /home/user/.openclaw/agents/writer/agent/auth-profiles.json

All 8 files should exist with identical or equivalent tokenRef content.

2. Verify Token Content Consistency

bash $ jq -r ‘.tokenRef’ ~/.openclaw/agents/main/agent/auth-profiles.json sk-ant-…

$ for agent in chief developer qa secretary lawyer writer experimenter; do echo -n “$agent: " jq -r ‘.tokenRef’ ~/.openclaw/agents/$agent/agent/auth-profiles.json 2>/dev/null || echo “MISSING” done chief: sk-ant-… developer: sk-ant-… qa: sk-ant-… secretary: sk-ant-… lawyer: sk-ant-… writer: sk-ant-… experimenter: sk-ant-…

All agents should display the same tokenRef (or equivalent value).

3. Test Agent Authentication via Gateway

bash $ openclaw gateway logs –follow & $ openclaw run –agent developer “echo test” 2>&1 | head -20

Should see no fallback warnings in gateway logs:

[2026-03-08T14:35:01Z] INFO: Agent ‘developer’ authenticated via agents/developer/agent/auth-profiles.json

4. Verify No Silent Fallback Occurs

bash $ grep -r “using free fallback” ~/.openclaw/agents/*/logs/gateway.log || echo “No fallbacks detected”

$ openclaw run –agent developer “what model are you”

Should respond as Claude Sonnet, not as GLM 4.5 Air

5. Verify Fixed Build (if Option A applied)

bash $ grep “agent.id” node_modules/openclaw/dist/commands/onboard.js const authDir = path.join(openclawHome, ‘agents’, agent.id, ‘agent’);

$ openclaw onboard –dry-run βœ“ Would write auth to: agents/chief/agent/auth-profiles.json βœ“ Would write auth to: agents/developer/agent/auth-profiles.json …

6. Exit Code Validation

bash $ openclaw onboard && echo “Exit code: $?” βœ“ Authenticated with Anthropic βœ“ Token written to all 8 agent directories βœ“ Onboarding complete Exit code: 0

⚠️ Common Pitfalls

Pitfall 1: Agent ID Mismatch

If your openclaw.json uses custom agent IDs that don’t match directory names:

json { “agents”: { “list”: [ { “id”: “prod-server”, “model”: “anthropic/claude-opus-4-6” } ] } }

The onboard command may fail silently if prod-server contains hyphens (OS-specific path issues on Windows).

Mitigation: Verify directory creation succeeds: bash ls -la ~/.openclaw/agents/prod-server/agent/

Pitfall 2: Mixed Auth Methods

If some agents use setup-token and others use OAuth: json { “agents”: { “list”: [ { “id”: “main”, “auth”: { “method”: “setup-token”, “provider”: “anthropic” } }, { “id”: “developer”, “auth”: { “method”: “oauth”, “provider”: “openai” } } ] } }

Onboard may overwrite OAuth tokens with setup-token refs. Always audit auth files post-onboard.

Mitigation: Review auth config per agent after onboarding: bash jq ‘.auth.method’ ~/.openclaw/agents/*/agent/auth-profiles.json

Pitfall 3: Docker Environment

When running in Docker, ~/.openclaw inside the container is ephemeral:

bash docker run –rm openclaw onboard

Tokens written to container’s ~/.openclaw, lost on exit

docker run -v openclaw-data:/root/.openclaw openclaw onboard

Tokens persist via volume mount

Mitigation: Mount persistent volume for auth data: bash docker run -v $(pwd)/openclaw-data:/root/.openclaw openclaw onboard

Pitfall 4: Windows Path Separator

On Windows, ~/.openclaw expands to %USERPROFILE%\.openclaw, but the code may use forward slashes:

powershell

Bug manifests as:

Writing to: C:\Users\user.openclaw\agents\main\agent\auth-profiles.json

But gateway reads: C:/Users/user/.openclaw/agents/main/agent/auth-profiles.json

$ openclaw onboard

May succeed but gateway cannot find file

Mitigation: Run openclaw verify-config before onboard on Windows.

Pitfall 5: Stale Token Cooldowns

If agents had previous failed auth attempts, they may be in error cooldown:

bash $ openclaw run –agent developer “test” Error: Rate limited (cooldown: 47 minutes remaining)

Mitigation: Clear cooldown state: bash rm ~/.openclaw/agents/developer/agent/auth-profiles.json openclaw onboard

Pitfall 6: Untracked Auth Files

Git-ignored auth-profiles.json files won’t be backed up:

bash $ cat .gitignore … agents/*/agent/auth-profiles.json # excluded

Onboarding on new machine β†’ no auth files exist

Main agent gets auth, others remain empty

Mitigation: Track auth file structure without content: bash

Commit directory skeleton:

mkdir -p agents/TEMPLATE/agent touch agents/TEMPLATE/agent/.gitkeep

#28293 β€” Non-default agents get 401 with same token

Symptom: Agents configured with identical tokenRef receive HTTP 401 from provider.

Difference: This issue stems from token expiry or scope validation; this bug (auth file distribution) causes the token to be unavailable in the first place.

Resolution: Verify token validity with openclaw auth verify; if valid, apply the onboard fix.


#38336 β€” OAuth renewal doesn’t update provisioned copy

Symptom: After OAuth token refresh via browser, CLI commands still fail auth for non-main agents.

Relationship: Demonstrates the same architectural gapβ€”auth updates flow to main agent only, leaving others in stale state.

Workaround: Manually sync after OAuth renewal: bash cp ~/.openclaw/agents/main/agent/auth-profiles.json
~/.openclaw/agents/*/agent/auth-profiles.json


EAUTH-001 β€” Auth profile not found

Symptom: EAUTH-001: No auth-profiles.json found for agent '{agent}'

Root: Agent directory doesn’t exist or was never provisioned by onboard.


EFAIL-202 β€” Silent fallback to free model

Symptom: Command succeeds but output quality is degraded (free model responses).

Root: Gateway detects missing auth and falls back without user notification.


EMODEL-404 β€” Model not available for agent

Symptom: Agent configured for anthropic/claude-opus-4-6 but receives “model not found” error.

Root: May indicate auth file exists but contains invalid/expired token; verify with openclaw auth status --agent {id}.

Evidence & Sources

This troubleshooting guide was automatically synthesized by the FixClaw Intelligence Pipeline from community discussions.