linshenkx/prompt-optimizer · error

Health check failed

Error message

Health check failed

What it means

The /healthz route of the MCP server calls healthProvider.getHealthStatus(); if that promise rejects (or a non-Error is thrown), the catch block returns HTTP 503 with initialized:false and the error message, defaulting to the literal 'Health check failed' when the thrown value is not an Error instance.

Solutions

  1. Check the response body's error field and the server logs to see which underlying dependency failed (the generic message means a non-Error was thrown — log the raw value).
  2. Fix the underlying dependency (DB/storage connection, env config) so getHealthStatus resolves.
  3. Configure liveness/readiness probe thresholds to tolerate startup, or have getHealthStatus return degraded status objects instead of throwing.

Example fix

// before
res.status(503).json({ initialized: false, services: {}, error: error instanceof Error ? error.message : 'Health check failed' });
// after (also log the raw failure for diagnosis)
console.error('[healthz] non-Error failure:', error);
res.status(503).json({ initialized: false, services: {}, error: error instanceof Error ? error.message : String(error) });
Defensive patterns

Strategy: try-catch

Type guard

const isHealthzFailure = (body: unknown): body is { initialized: false; error: string } =>
  typeof body === 'object' && body !== null && (body as any).initialized === false

Try / catch

const res = await fetch(`${MCP_URL}/healthz`)
if (res.status === 503) {
  const body = await res.json().catch(() => null)
  log.warn('MCP unhealthy:', body?.error ?? 'unknown')
  // retry with backoff; if the message is the generic 'Health check failed', a non-Error was thrown server-side
}

Prevention

When it happens

Trigger: GET /healthz while a dependency checked by getHealthStatus is down or throws — e.g. storage/DB unreachable, a service not yet initialized — or when getHealthStatus itself has a bug and throws a string/non-Error value (which surfaces as the generic message).

Common situations: Kubernetes/container probes hitting /healthz before dependencies are ready; misconfigured connection strings causing getHealthStatus to reject; version changes to the health provider API throwing TypeError instead of structured status.

Related errors


AI-assisted analysis of linshenkx/prompt-optimizer@3e677b1d9f (2026-08-27). Data as JSON: /api/errors/416f78fe22e1edaa. Report an issue: GitHub.

Appendix: source

Thrown at packages/mcp-server/src/health.ts:29

export function buildHealthzResponse(healthStatus: MCPHealthStatus): {
  statusCode: number;
  body: MCPHealthStatus;
} {
  return {
    statusCode: isHealthyStatus(healthStatus) ? 200 : 503,
    body: healthStatus
  };
}

export function registerHealthzRoute(app: Express, healthProvider: HealthStatusProvider): void {
  app.get('/healthz', async (_req, res) => {
    try {
      const healthStatus = await healthProvider.getHealthStatus();
      const { statusCode, body } = buildHealthzResponse(healthStatus);
      res.status(statusCode).json(body);
    } catch (error) {
      res.status(503).json({
        initialized: false,
        services: {},
        error: error instanceof Error ? error.message : 'Health check failed'
      });
    }
  });
}

View on GitHub (pinned to 3e677b1d9f)