paperclipai/paperclip · error · RuntimeServicePortBindCollision
Runtime service could not bind allocated port ${port} (${dia
Error message
Runtime service could not bind allocated port ${port} (${diagnosis}) What it means
The runtime service reported EADDRINUSE-class bind failure on its allocated port, diagnosed as a bind collision; startLocalRuntimeService re-runs allocation skipping quarantined port pairs, and the collision is thrown as a retryable error.
Source
Thrown at server/src/services/workspace-runtime.ts:6163
if (bindCollision && port) throw new RuntimeServicePortBindCollision(port);
if (exposureHostCollision && port) {
// A verified host listener holds the assigned exposure port. Quarantine the
// pair so the bounded re-allocation never re-offers it, then throw a retryable
// collision. `startLocalRuntimeService` re-runs allocation, which skips the
// quarantined pair and takes the next free pair inside the dedicated range.
// This hardens a real host that races an external process for a range port.
for (const collisionPort of exposureCollisionPorts) {
quarantinedRuntimeExposurePorts.add(collisionPort);
}
if (input.onLog) {
await input.onLog(
"stderr",
`[service:${serviceName}] exposure port ${port} collided during startup (EADDRINUSE); `
+ `${exposureCollisionDiagnosis ?? "owner unavailable"}. `
+ `Quarantined pair ${exposureCollisionPorts.join("/")} and reallocating.\n`,
).catch(() => undefined);
}
throw new RuntimeServicePortBindCollision(port, exposureCollisionDiagnosis, true);
}
const deploymentBindConflict = /local_trusted requires server\.bind=loopback/i.test(
`${failureMessage}\n${serviceOutputExcerpt}`,
);
// The guest reported an assigned-port EADDRINUSE, but no host listener owned
// the port. Explain that the runtime did not quarantine the pair, so a future
// occurrence needs no diagnostic cycle and the pool stays intact.
const unverifiedExposureCollision = exposureTextNamesAssignedPort && !exposureHostCollision;
const actionableFailure = deploymentBindConflict
? `${failureMessage} | deployment/bind conflict: local_trusted requires server.bind=loopback; the managed runtime requested an incompatible bind mode`
: unverifiedExposureCollision
? `${failureMessage} | exposure port collision not verified: the guest reported EADDRINUSE on assigned port ${exposureNamedPorts.join("/")}, but no host listener owns it (${exposureCollisionDiagnosis ?? "owner unavailable"}); the runtime did not quarantine the pair`
: failureMessage;
throw new Error(
`Failed to start runtime service "${serviceName}": ${actionableFailure}${serviceOutputExcerpt ? ` | output: ${serviceOutputExcerpt.trim()}` : ""}`,
);
});
View on GitHub (pinned to a7e689b3c3)
Solutions
- Let the bounded re-allocation retry pick the next free port pair
- Free the collided port or stop the external process holding it
- Check the quarantine list is not exhausted for the dedicated port range
- Inspect the bind diagnosis in the error for owner information
Defensive patterns
Strategy: retry
When it happens
Trigger: Thrown at server/src/services/workspace-runtime.ts:6163 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of paperclipai/paperclip@a7e689b3c3 (2026-08-21).
Data as JSON: /api/errors/7aec51b02fed2dbb.
Report an issue: GitHub.