sipeed/picoclaw · error

Failed to start gateway: %v

Error message

Failed to start gateway: %v

What it means

Returned by POST /api/gateway/start when h.startGatewayLocked("starting", 0) fails to spawn a new gateway subprocess. Reading gateway.go:1008-1061, failure points are: config.LoadConfig (wrapped as 'failed to load config'), utils.FindPicoclawBinary() not locating the picoclaw executable, StdoutPipe/StderrPipe creation failing (usually fd exhaustion), or cmd.Start failing (exec format error, fork failure, missing binary). The wrapped %v identifies which stage died.

Source

Thrown at web/backend/api/gateway.go:1249

			w,
			fmt.Sprintf("Failed to validate gateway start conditions: %v", err),
			http.StatusInternalServerError,
		)
		return
	}
	if !ready {
		w.Header().Set("Content-Type", "application/json")
		w.WriteHeader(http.StatusBadRequest)
		json.NewEncoder(w).Encode(map[string]any{
			"status":  "precondition_failed",
			"message": reason,
		})
		return
	}

	pid, err := h.startGatewayLocked("starting", 0)
	if err != nil {
		http.Error(w, fmt.Sprintf("Failed to start gateway: %v", err), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(map[string]any{
		"status": "ok",
		"pid":    pid,
	})
}

// handleGatewayStop stops the running gateway subprocess gracefully.
// Note: Unlike StopGateway (which only stops self-started processes), this API endpoint
// stops any gateway process, including attached ones. This is intentional for user control.
//
//	POST /api/gateway/stop
func (h *Handler) handleGatewayStop(w http.ResponseWriter, r *http.Request) {
	gateway.mu.Lock()
	defer gateway.mu.Unlock()

View on GitHub (pinned to 49183d7e8d)

Solutions

  1. Read the wrapped message: 'failed to load config' -> fix the config file (see error 902); pipe errors -> raise fd limits; exec errors -> fix the binary
  2. Ensure the picoclaw executable exists, is installed next to the launcher or on PATH, and has the execute bit set
  3. Check 'ulimit -n' and raise it if StdoutPipe/StderrPipe creation is failing
  4. Retry POST /api/gateway/start after fixing the underlying cause
Defensive patterns

Strategy: try-catch

Try / catch

const res = await fetch('/api/gateway/start', {method: 'POST'});
if (!res.ok) {
  const text = await res.text();
  if (text.includes('failed to load config')) throw new Error('Config file broken - repair it first');
  if (text.includes('pipe')) throw new Error('OS fd limit hit - raise ulimit -n and restart the backend');
  if (text.includes('picoclaw') || text.toLowerCase().includes('executable')) throw new Error('picoclaw binary not found - reinstall or fix PATH');
  throw new Error(text);
}

Prevention

When it happens

Trigger: picoclaw binary not on PATH and not beside the launcher binary (FindPicoclawBinary returns nothing usable); fd limit (ulimit -n) exhausted so pipe creation fails; exec bit lost after copying the binary; config file unreadable (wrapped 'failed to load config').

Common situations: Running the web backend from a different working directory or container image that omits the gateway binary; upgrading picoclaw and leaving a renamed/removed old binary; CI or constrained environments with low fd limits.

Related errors


AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15). Data as JSON: /api/errors/d238e8eca1065133. Report an issue: GitHub.