paperclipai/paperclip · error
Timed out waiting for workspace restore lock at
Error message
Timed out waiting for workspace restore lock at ${lockDir} What it means
Error "Timed out waiting for workspace restore lock at ${lockDir}" thrown in paperclipai/paperclip.
Solutions
- Remove the stale workspace restore lock at ${lockDir} if no process holds it, then retry.
- Wait for the concurrent restore to finish and retry.
When it happens
Trigger: Thrown at packages/adapter-utils/src/workspace-restore-merge.ts:154 when the library encounters an invalid state.
Common situations: See trigger scenarios.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-08-18).
Data as JSON: /api/errors/c4f9db16e87f5df9.
Report an issue: GitHub.
Appendix: source
Thrown at packages/adapter-utils/src/workspace-restore-merge.ts:235
| { readonly ok: true }
| { readonly ok: false; readonly code: WorkspaceRestoreFailureCode };
/**
* Classifies a caught workspace-restore error into one allowlisted code. Maps
* `EACCES` and `EPERM` to a permission failure, the merge-lock timeout
* (matched by {@link WORKSPACE_RESTORE_LOCK_TIMEOUT_CODE}, never by the error
* message text) to a lock-timeout failure, and every other error to a generic
* failure. Never reads or returns `Error.message`, a filesystem path, or a
* process id.
*/
export function classifyWorkspaceRestoreFailure(error: unknown): WorkspaceRestoreFailureCode {
const code = error && typeof error === "object" ? (error as NodeJS.ErrnoException).code : undefined;
if (code === "EACCES" || code === "EPERM") return "restore_permission_denied";
if (code === WORKSPACE_RESTORE_LOCK_TIMEOUT_CODE) return "restore_lock_timeout";
return "restore_failed";
}
/**
* The fixed, allowlisted line an ACP adapter writes to the run log when a
* workspace restore fails. Every call site must pass this to `onLog` instead
* of the caught error's own message: the caught error can carry a host
* filesystem path or the lock owner's process id, and the run log is
* readable by any same-company actor. Never add the code's raw
* `Error.message` to this text.
*/
export function describeWorkspaceRestoreFailure(code: WorkspaceRestoreFailureCode): string {
switch (code) {
case "restore_permission_denied":
return "the restore could not write to the workspace (permission denied)";
case "restore_lock_timeout":
return "the restore timed out waiting for the workspace merge lock";
case "restore_failed":
return "the restore failed";
}
}
View on GitHub (pinned to 01ad858492)