- Setup wizard with auto-detection of OpenClaw paths and Claude CLI - Token sync watcher (inotifywait) for real-time credential updates - Auto-refresh trigger timer that runs Claude CLI every 30 min - Supports Claude CLI in Docker container or on host - Temporary ANTHROPIC_BASE_URL override for container environments - Anthropic model configuration for OpenClaw - Auth profile management (fixes key vs access field) - Systemd services and timers for both sync and trigger - Comprehensive documentation and troubleshooting guides - Re-authentication notification system Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
155 lines
4.1 KiB
Markdown
155 lines
4.1 KiB
Markdown
# Troubleshooting
|
|
|
|
## "HTTP 401 authentication_error: OAuth token has expired"
|
|
|
|
The most common error. The OAuth token has a ~8 hour lifetime.
|
|
|
|
**Check:**
|
|
1. Is the sync service running? `systemctl status sync-oauth-token.service`
|
|
2. Is inotifywait watching? `pgrep -af inotifywait`
|
|
3. Is the source credentials file being updated? `stat /root/.openclaw/workspaces/workspace-claude-proxy/config/.claude/.credentials.json`
|
|
4. Check service logs: `journalctl -u sync-oauth-token.service -f`
|
|
|
|
**Fix:**
|
|
- If service stopped: `systemctl restart sync-oauth-token.service`
|
|
- If token expired everywhere: run `./scripts/refresh-claude-token.sh` manually
|
|
- Nuclear option: `claude login` inside the Claude CLI container, then restart sync service
|
|
|
|
---
|
|
|
|
## "docker compose restart doesn't reload .env"
|
|
|
|
This is a Docker Compose design behavior, not a bug.
|
|
|
|
`docker compose restart` only sends SIGTERM and restarts the container process. The container keeps its original environment variables from creation time.
|
|
|
|
**Always use:**
|
|
```bash
|
|
cd /root/openclaw
|
|
docker compose down openclaw-gateway
|
|
docker compose up -d openclaw-gateway
|
|
```
|
|
|
|
This destroys the container and creates a new one, reading `.env` fresh.
|
|
|
|
---
|
|
|
|
## Auth profile has "key" field instead of "access"
|
|
|
|
OpenClaw's `isValidProfile()` for `type: "oauth"` checks for `cred.access`, not `cred.key`. If your auth profile looks like:
|
|
|
|
```json
|
|
{
|
|
"anthropic:default": {
|
|
"type": "oauth",
|
|
"provider": "anthropic",
|
|
"key": "sk-ant-oat01-..." <-- WRONG
|
|
}
|
|
}
|
|
```
|
|
|
|
The profile is silently skipped and falls through to the env var.
|
|
|
|
**Fix:** Run `./scripts/fix-auth-profiles.sh`
|
|
|
|
The correct format is:
|
|
```json
|
|
{
|
|
"anthropic:default": {
|
|
"type": "oauth",
|
|
"provider": "anthropic",
|
|
"access": "sk-ant-oat01-..." <-- CORRECT
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## "404 model_not_found" or double /v1 in URL
|
|
|
|
This happens when you add `anthropic` to `models.providers` in `openclaw.json`.
|
|
|
|
**Do NOT do this:**
|
|
```json
|
|
"models": {
|
|
"providers": {
|
|
"anthropic": {
|
|
"baseUrl": "https://api.anthropic.com/v1", <-- WRONG
|
|
...
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
The built-in Anthropic provider already handles routing. Adding a custom one with `baseUrl` ending in `/v1` causes the SDK to append another `/v1`, resulting in `https://api.anthropic.com/v1/v1/messages` -> 404.
|
|
|
|
**Fix:** Remove any `anthropic` entry from `models.providers`. The built-in provider handles it automatically when you reference `anthropic/claude-opus-4-6` as the model.
|
|
|
|
---
|
|
|
|
## "No available auth profile for anthropic (all in cooldown)"
|
|
|
|
Auth profiles enter a cooldown period after repeated failures (e.g., expired tokens, wrong model names).
|
|
|
|
**Fix:**
|
|
```bash
|
|
./scripts/fix-auth-profiles.sh
|
|
```
|
|
|
|
This clears `cooldownUntil`, `errorCount`, and `failureCounts` from all agent auth profiles.
|
|
|
|
---
|
|
|
|
## inotifywait: "No such file or directory"
|
|
|
|
The watched file or directory doesn't exist yet.
|
|
|
|
**Check:**
|
|
- Does the Claude CLI container exist? `docker ps | grep claude`
|
|
- Does the credentials path exist? `ls -la /root/.openclaw/workspaces/workspace-claude-proxy/config/.claude/`
|
|
- Has Claude CLI been authenticated? You may need to run `claude login` inside the container first.
|
|
|
|
---
|
|
|
|
## Gateway starts but Anthropic model still fails
|
|
|
|
After recreating the gateway, wait a few seconds for it to fully start. Then verify:
|
|
|
|
```bash
|
|
# Check container has the new token
|
|
docker exec openclaw-openclaw-gateway-1 printenv ANTHROPIC_OAUTH_TOKEN
|
|
|
|
# Check oauth.json was picked up
|
|
docker exec openclaw-openclaw-gateway-1 cat /home/node/.openclaw/credentials/oauth.json
|
|
```
|
|
|
|
---
|
|
|
|
## Checking logs
|
|
|
|
```bash
|
|
# Real-time sync service logs
|
|
journalctl -u sync-oauth-token.service -f
|
|
|
|
# Last 50 log entries
|
|
journalctl -u sync-oauth-token.service -n 50
|
|
|
|
# Gateway container logs
|
|
docker logs openclaw-openclaw-gateway-1 --tail 100
|
|
|
|
# Force a re-sync
|
|
systemctl restart sync-oauth-token.service
|
|
```
|
|
|
|
---
|
|
|
|
## Complete reset procedure
|
|
|
|
If everything is broken:
|
|
|
|
1. Get a fresh token: `docker exec -it claude-proxy claude login`
|
|
2. Fix auth profiles: `./scripts/fix-auth-profiles.sh`
|
|
3. Restart sync service: `systemctl restart sync-oauth-token.service`
|
|
4. Wait 10 seconds for sync to complete
|
|
5. Verify: `./scripts/verify.sh`
|