sipeed/picoclaw · error
Failed to validate gateway start conditions: %v
Error message
Failed to validate gateway start conditions: %v
What it means
Returned by POST /api/gateway/start when a live PID file exists and h.gatewayStartReady() returns an error. Reading gateway.go:371-375, the only error path in gatewayStartReady is config.LoadConfig(h.configPath) failing - the picoclaw config file cannot be read or parsed. This is deliberately distinct from the 400 precondition_failed branch, which handles semantic problems (no default model, invalid model, missing credentials, unreachable local model). A 500 here means the config file itself is unreadable or syntactically broken.
Source
Thrown at web/backend/api/gateway.go:1185
}
}()
return pid, nil
}
// handleGatewayStart starts the picoclaw gateway subprocess.
//
// POST /api/gateway/start
func (h *Handler) handleGatewayStart(w http.ResponseWriter, r *http.Request) {
// Check PID file first to detect an already-running gateway.
pidData := h.sanitizeGatewayPidData(ppid.ReadPidFileWithCheck(globalConfigDir()), nil)
if pidData != nil {
pid := pidData.PID
gateway.mu.Lock()
ready, reason, err := h.gatewayStartReady()
if err != nil {
gateway.mu.Unlock()
http.Error(
w,
fmt.Sprintf("Failed to validate gateway start conditions: %v", err),
http.StatusInternalServerError,
)
return
}
if !ready {
gateway.mu.Unlock()
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusBadRequest)
json.NewEncoder(w).Encode(map[string]any{
"status": "precondition_failed",
"message": reason,
})
return
}
_, err = h.startGatewayLocked("starting", pid)
if err != nil {View on GitHub (pinned to 49183d7e8d)
Solutions
- Call GET /api/config - it hits the same config.LoadConfig and its error text shows the exact parse/read failure
- Fix the reported syntax error, or restore the config file from backup
- Verify the config file is readable by the user running the backend process (check ownership and mode)
- Retry POST /api/gateway/start once the config loads cleanly
Defensive patterns
Strategy: validation
Validate before calling
// Probe config loadability before starting the gateway -
// GET /api/config exercises the same config.LoadConfig call.
const probe = await fetch('/api/config');
if (!probe.ok) {
const detail = await probe.text(); // e.g. the YAML/JSON parse error
throw new Error('config file is broken, fix before gateway start: ' + detail);
} Try / catch
const res = await fetch('/api/gateway/start', {method: 'POST'});
if (res.status === 500) {
const text = await res.text();
if (text.startsWith('Failed to validate gateway start conditions')) {
// infrastructure failure: config unreadable -> route user to config repair, do NOT retry blindly
await router.push('/settings/config');
}
throw new Error(text);
} Prevention
- Never hand-edit the config file while the launcher is running; use PUT /api/config so writes are validated
- Watch GET /api/config for 500s as a canary in health checks
- Keep config file ownership aligned with the user running the backend
When it happens
Trigger: config.json/yaml was hand-edited and left with a syntax error while the launcher runs; the config file was deleted, moved, or truncated; file permissions changed so the backend user can no longer read it; the config sits on a network mount that just dropped.
Common situations: Editing the config in an external editor with an unsaved/invalid intermediate state; running the web backend under a different user (systemd unit, container) than the one owning the config file; a crashed disk-full write left a zero-length config.
Related errors
- error creating channel manager: %w
- error creating new provider: %w
- feishu channel is not supported on 32-bit architectures (arm
- must be in range 1-65535
- create request: %w
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/905983b867ca6490.
Report an issue: GitHub.