plandex-ai/plandex · error · shared.ApiError
{apiErr.Msg}
Error message
{apiErr.Msg} What it means
This is the /health endpoint of the Plandex server surfacing a failure from the hooks.HealthCheck hook. When ExecHook returns a non-nil apiErr, the handler logs it and writes apiErr.Msg with apiErr.Status back to the client. The error means a registered health-check hook failed, so the server is reporting itself unhealthy.
Source
Thrown at app/server/routes/routes.go:37
func RegisterHandlePlandex(fn HandlePlandex) {
HandlePlandexFn = fn
}
func EnsureHandlePlandex() {
if HandlePlandexFn == nil {
panic("handlePlandexFn is not set")
}
}
func AddHealthRoutes(r *mux.Router) {
EnsureHandlePlandex()
HandlePlandexFn(r, "/health", false, func(w http.ResponseWriter, r *http.Request) {
_, apiErr := hooks.ExecHook(hooks.HealthCheck, hooks.HookParams{})
if apiErr != nil {
log.Printf("Error in health check hook: %v\n", apiErr)
http.Error(w, apiErr.Msg, apiErr.Status)
return
}
fmt.Fprint(w, "OK")
})
HandlePlandexFn(r, "/version", false, func(w http.ResponseWriter, r *http.Request) {
// Log the host
host := r.Host
log.Printf("Host header: %s", host)
execPath, err := os.Executable()
if err != nil {
log.Fatal("Error getting current directory: ", err)
}
currentDir := filepath.Dir(execPath)
// get version from version.txt
var path stringView on GitHub (pinned to e2d772072e)
Solutions
- Check the server logs for 'Error in health check hook' to see the underlying hook error and its cause
- Verify the dependencies probed by the health-check hook (database, external services) are reachable and credentials are correct
- Retry /health once dependencies are restored; the message is per-request, not sticky
- If the hook itself is buggy, inspect hooks.ExecHook(hooks.HealthCheck) implementations and fix or unregister the failing hook
Example fix
// before
_, apiErr := hooks.ExecHook(hooks.HealthCheck, hooks.HookParams{})
if apiErr != nil {
http.Error(w, apiErr.Msg, apiErr.Status)
return
}
// after
_, apiErr := hooks.ExecHook(hooks.HealthCheck, hooks.HookParams{})
if apiErr != nil {
log.Printf("health check failed: %v (msg=%s status=%d)", apiErr, apiErr.Msg, apiErr.Status)
http.Error(w, apiErr.Msg, apiErr.Status)
return
} Defensive patterns
Strategy: try-catch
Try / catch
resp, err := http.Get(serverURL + "/health")
if err != nil {
// server unreachable entirely
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(resp.Body)
return fmt.Errorf("health check failed (status %d): %s", resp.StatusCode, string(body))
} Prevention
- Use the HTTP status code from /health as the health signal, not just connection success
- Monitor server logs for 'Error in health check hook' to catch dependency failures early
- Configure orchestrator probes with a small retry/period so transient dependency blips don't kill the server
- Keep health-check hook dependencies (DB DSN, service endpoints) in validated startup config
When it happens
Trigger: Any registered hooks.HealthCheck hook returns an api.ApiError: typically a failed internal dependency check (e.g. database unreachable, migration failure, or another subsystem the hook probes) during GET /health.
Common situations: Load balancers or Kubernetes liveness/readiness probes hitting /health while the database is down or misconfigured; starting the server before its backing services are ready; broken hook registration after upgrades.
Related errors
- Error error updating contexts:
- Error getting branch:
- Error deleting contexts:
- token exchange failed - error creating request: %s
- token exchange failed - error reading body: %s
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/a9999ec593e6d164.
Report an issue: GitHub.