sipeed/picoclaw · error
token login failed: %v
Error message
token login failed: %v
What it means
Returned as HTTP 500 by POST /api/oauth/login (token method) when persistCredentialAndConfig fails. That function does two things that can error: auth.SetCredential (load + save the credential store file on disk) and syncProviderAuthMethod (load + save picoclaw's config.json at h.configPath). The wrapped %v tells you which stage failed ("saving credential: ..." or "syncing provider auth config: ..."). The token itself is never validated against the provider at this step, so this error is always a local persistence failure, not a bad token.
Source
Thrown at web/backend/api/oauth.go:221
)
return
}
switch method {
case oauthMethodToken:
token := strings.TrimSpace(req.Token)
if token == "" {
http.Error(w, "token is required", http.StatusBadRequest)
return
}
cred := &auth.AuthCredential{
AccessToken: token,
Provider: provider,
AuthMethod: oauthMethodToken,
}
if err := h.persistCredentialAndConfig(provider, oauthMethodToken, cred); err != nil {
http.Error(w, fmt.Sprintf("token login failed: %v", err), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
_ = json.NewEncoder(w).Encode(map[string]any{
"status": "ok",
"provider": provider,
"method": method,
})
return
case oauthMethodDeviceCode:
cfg := auth.OpenAIOAuthConfig()
info, err := oauthRequestDeviceCode(cfg)
if err != nil {
http.Error(w, fmt.Sprintf("failed to request device code: %v", err), http.StatusInternalServerError)
return
}View on GitHub (pinned to 49183d7e8d)
Solutions
- Read the wrapped detail: "saving credential: ..." means the auth store, "syncing provider auth config: ..." means config.json.
- Check the config file path the backend was started with (h.configPath) is readable and writable by the backend process user.
- Inspect the credential store file (auth store location, e.g. under the picoclaw config dir) for corruption; if it is not valid JSON, rename it away and retry login to recreate it.
- Fix ownership/permissions (chown/chmod) or free disk space, then retry the login POST.
Example fix
# before: backend user cannot write config
$ ls -l /etc/picoclaw/config.json
-rw-r--r-- 1 root root ... config.json # 500 token login failed: syncing provider auth config: ...
# after
$ sudo chown $(whoami) /etc/picoclaw/config.json && curl -X POST http://localhost:8080/api/oauth/login -d '{"provider":"openai","method":"token","token":"sk-..."}' Defensive patterns
Strategy: try-catch
Validate before calling
await fs.access(configPath, fs.constants.W_OK | fs.constants.R_OK); // fail fast if config.json is not writable const st = await fs.stat(credsFile); // ensure the credential store exists and is readable await fs.access(credsFile, fs.constants.W_OK);
Try / catch
const res = await fetch('/api/oauth/login', {...});
if (res.status === 500) {
const { message } = await res.json();
if (message?.startsWith('token login failed')) {
// local persistence failure — surface filesystem detail, do NOT retry with the same broken state
throw new Error(`Login could not be saved: ${message}`);
}
throw new Error(message);
} Prevention
- Run the backend as the user that owns the config dir and credential store.
- Validate config.json and the credentials file parse as JSON before starting login flows.
- A 500 here is never a bad token — do not ask the user to re-paste the token; fix the filesystem first.
When it happens
Trigger: POST /api/oauth/login {"provider":"openai","method":"token","token":"sk-..."} when the credential store file is unreadable/corrupt (SetCredential → LoadStore fails), the credentials file or config.json is read-only, or the directory is not writable (SaveStore/SaveConfig fail).
Common situations: Running the backend as a different user than the one who owns ~/.config/picoclaw (permission denied); a partially written or hand-edited credential store with invalid JSON; disk full; config.json mounted read-only in a container.
Related errors
- failed to delete credential: %v
- failed to load credentials: %v
- failed to update config: %v
- error adding job: %w
- failed to save config: %w
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/3bf51f6016d6c382.
Report an issue: GitHub.