paperclipai/paperclip · error · RuntimeServicePortBindCollision
Runtime service could not bind allocated port ${port}
Error message
Runtime service could not bind allocated port ${port} What it means
The service process is alive but has not bound its allocated port before the readiness timeout expired. The service is hanging or listening elsewhere, so the managed runtime service start is failed.
Source
Thrown at server/src/services/workspace-runtime.ts:4819
throw new Error(`Readiness check failed for ${readinessUrl}: ${lastError}`);
}
async function waitForAllocatedPortBind(input: {
service: Record<string, unknown>;
port: number;
child: ChildProcess;
}) {
const deadline = Date.now() + resolveWorkspaceRuntimeReadinessTimeoutSec(input.service) * 1000;
while (Date.now() < deadline) {
if (input.child.exitCode !== null || input.child.signalCode !== null) {
throw new Error("service process exited before binding its allocated port");
}
const ownerPid = await readLocalServicePortOwner(input.port);
if (ownerPid) {
const childPid = input.child.pid ?? null;
if (!childPid || !(await isLocalServiceProcessOwnedBy(ownerPid, childPid))) {
throw new RuntimeServicePortBindCollision(input.port);
}
// Require the same launched process group to retain ownership across a stability delay.
// Cwd matching alone is insufficient because sibling services can share a workspace.
await delay(250);
if (input.child.exitCode !== null || input.child.signalCode !== null) {
throw new Error("service process exited after losing its allocated port");
}
const stableOwnerPid = await readLocalServicePortOwner(input.port);
if (!stableOwnerPid || !(await isLocalServiceProcessOwnedBy(stableOwnerPid, childPid))) {
throw new RuntimeServicePortBindCollision(input.port);
}
return;
}
// A present listener proves only that some listener appeared. If listener ownership cannot
// be attributed to this child after a stability delay, retry instead of accepting a sibling.
// The presence read never binds the port, so it cannot steal the port from the child.
if (await hasLoopbackPortListener(input.port)) {View on GitHub (pinned to a7e689b3c3)
Solutions
- Make the runtime service listen on the allocated port, or configure a different free port.
- Check that nothing else grabbed the port between allocation and bind, then retry.
Defensive patterns
Strategy: retry
When it happens
Trigger: Thrown at server/src/services/workspace-runtime.ts:4666 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of paperclipai/paperclip@a7e689b3c3 (2026-08-18).
Data as JSON: /api/errors/0c0de89477ef2e99.
Report an issue: GitHub.