paperclipai/paperclip · error · Error
Paperclip service did not become healthy
Error message
Paperclip service did not become healthy${expectedVersion ? ` at version ${expectedVersion}` : ""}: ${last.error ?? `reported ${last.serverVersion ?? "no version"}`} What it means
Error "Paperclip service did not become healthy${expectedVersion ? ` at version ${expectedVersion}` : ""}: ${last.error ?? `reported ${last.serverVersion ?? "no version"}`}" thrown in paperclipai/paperclip.
Solutions
- Check service logs for the startup failure, fix the cause, and restart the service.
When it happens
Trigger: Thrown at cli/src/commands/service.ts:50 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of paperclipai/paperclip@120ae5428f (2026-08-18).
Data as JSON: /api/errors/2b3cdfdb94fe4bd0.
Report an issue: GitHub.
Appendix: source
Thrown at cli/src/commands/service.ts:50
async function probeHealth(instanceId: string): Promise<HealthResult> {
try {
const response = await fetch(healthUrl(instanceId), { signal: AbortSignal.timeout(2_000) });
const body = await response.json() as { status?: unknown; serverVersion?: unknown; version?: unknown };
return { ok: response.ok && body.status === "ok", serverVersion: typeof body.serverVersion === "string" ? body.serverVersion : typeof body.version === "string" ? body.version : null };
} catch (error) {
return { ok: false, serverVersion: null, error: error instanceof Error ? error.message : String(error) };
}
}
async function waitForHealth(instanceId: string, expectedVersion: string | null, timeoutMs = 60_000): Promise<HealthResult> {
const deadline = Date.now() + timeoutMs;
let last: HealthResult = { ok: false, serverVersion: null };
while (Date.now() < deadline) {
last = await probeHealth(instanceId);
if (last.ok && (!expectedVersion || last.serverVersion === expectedVersion)) return last;
await new Promise((resolve) => setTimeout(resolve, 500));
}
throw new Error(`Paperclip service did not become healthy${expectedVersion ? ` at version ${expectedVersion}` : ""}: ${last.error ?? `reported ${last.serverVersion ?? "no version"}`}`);
}
export function resolveRestartExpectedVersion(expectedVersion: string | null | undefined): string | null {
return expectedVersion ?? null;
}
export async function withHotRestartLock<T>(
instanceId: string,
callback: () => Promise<T>,
options: { timeoutMs?: number; pollMs?: number; isProcessAlive?: (pid: number) => boolean } = {},
): Promise<T> {
const instanceRoot = resolvePaperclipInstanceRoot(instanceId);
const lockPath = path.join(instanceRoot, "hot-restart.lock");
const token = `${process.pid}:${Date.now()}:${Math.random().toString(16).slice(2)}`;
const deadline = Date.now() + (options.timeoutMs ?? 120_000);
const pollMs = options.pollMs ?? 100;
const isProcessAlive = options.isProcessAlive ?? ((pid: number) => {
try {View on GitHub (pinned to 120ae5428f)