paperclipai/paperclip · error · AuthorizationError
listener_ownership_mismatch
listener_ownership_mismatch
Error message
runtime id does not match lease
What it means
AuthorizationError from authorizeRemoval: a lease matching the handle was found, but the requesting runtime's UUID differs from the runtime bound at expose time. Enforces runtime isolation — runtime A can never remove runtime B's listener even with a leaked handle.
Source
Thrown at packages/tailscale-https-broker/src/authorization.ts:81
return timingSafeEqual(ab, bb);
}
/**
* Resolve the lease a `remove` request is authorized to act on. Requires an
* exact handle match AND that the requesting peer + runtime UUID match the
* lease bound at expose time. Runtime A can never remove runtime B's listener.
*/
export function authorizeRemoval(
leases: readonly LeaseRecord[],
request: { runtimeId: string; handle: string },
peer: PeerCredentials,
): LeaseRecord {
const lease = leases.find((entry) => handlesEqual(entry.handle, request.handle));
if (!lease) {
throw new AuthorizationError("invalid_handle", "unknown or stale lease handle");
}
if (lease.runtimeId !== request.runtimeId) {
throw new AuthorizationError("listener_ownership_mismatch", "runtime id does not match lease");
}
if (lease.peerUid !== peer.uid || lease.peerGid !== peer.gid) {
throw new AuthorizationError("listener_ownership_mismatch", "peer identity does not match lease");
}
return lease;
}
View on GitHub (pinned to 120ae5428f)
Solutions
- Use the runtime id that owns the lease, or acquire a fresh lease for this runtime.
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at packages/tailscale-https-broker/src/authorization.ts:81 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/318d0b013fd8bc81.
Report an issue: GitHub.