{"record":{"id":"c4f9db16e87f5df9","repo":"paperclipai/paperclip","slug":"timed-out-waiting-for-workspace-restore-lock-at","errorCode":null,"errorMessage":"Timed out waiting for workspace restore lock at ${lockDir}","messagePattern":"Timed out waiting for workspace restore lock at (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/adapter-utils/src/workspace-restore-merge.ts","lineNumber":235,"sourceCode":"  | { readonly ok: true }\n  | { readonly ok: false; readonly code: WorkspaceRestoreFailureCode };\n\n/**\n * Classifies a caught workspace-restore error into one allowlisted code. Maps\n * `EACCES` and `EPERM` to a permission failure, the merge-lock timeout\n * (matched by {@link WORKSPACE_RESTORE_LOCK_TIMEOUT_CODE}, never by the error\n * message text) to a lock-timeout failure, and every other error to a generic\n * failure. Never reads or returns `Error.message`, a filesystem path, or a\n * process id.\n */\nexport function classifyWorkspaceRestoreFailure(error: unknown): WorkspaceRestoreFailureCode {\n  const code = error && typeof error === \"object\" ? (error as NodeJS.ErrnoException).code : undefined;\n  if (code === \"EACCES\" || code === \"EPERM\") return \"restore_permission_denied\";\n  if (code === WORKSPACE_RESTORE_LOCK_TIMEOUT_CODE) return \"restore_lock_timeout\";\n  return \"restore_failed\";\n}\n\n/**\n * The fixed, allowlisted line an ACP adapter writes to the run log when a\n * workspace restore fails. Every call site must pass this to `onLog` instead\n * of the caught error's own message: the caught error can carry a host\n * filesystem path or the lock owner's process id, and the run log is\n * readable by any same-company actor. Never add the code's raw\n * `Error.message` to this text.\n */\nexport function describeWorkspaceRestoreFailure(code: WorkspaceRestoreFailureCode): string {\n  switch (code) {\n    case \"restore_permission_denied\":\n      return \"the restore could not write to the workspace (permission denied)\";\n    case \"restore_lock_timeout\":\n      return \"the restore timed out waiting for the workspace merge lock\";\n    case \"restore_failed\":\n      return \"the restore failed\";\n  }\n}\n","sourceCodeStart":217,"sourceCodeEnd":253,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/adapter-utils/src/workspace-restore-merge.ts#L217-L253","documentation":"Error \"Timed out waiting for workspace restore lock at ${lockDir}\" thrown in paperclipai/paperclip.","triggerScenarios":"Thrown at packages/adapter-utils/src/workspace-restore-merge.ts:154 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","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."],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-08-18T22:49:45.177Z","contentChangedAt":"2026-08-18T22:49:45.177Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}