{"record":{"id":"41d445f7d613ba60","repo":"paperclipai/paperclip","slug":"paperclip-runner-attachment-staging-cleanup-failed","errorCode":"paperclip_runner_attachment_staging_cleanup_failed","errorMessage":"paperclip_runner_attachment_staging_cleanup_failed","messagePattern":"paperclip_runner_attachment_staging_cleanup_failed","errorType":"error_code","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"server/src/services/native-runtime/native-runner-file-handoff.ts","lineNumber":1043,"sourceCode":"        staged.push({\n          id: row.id,\n          filename: row.filename?.trim() || \"attachment\",\n          contentType: row.contentType,\n          byteSize: row.byteSize,\n          workspaceRelativePath: null,\n          unavailableReason: \"attachment_staging_failed\",\n        });\n      }\n    }\n    return {\n      attachments: staged,\n      cleanup: async () => {\n        try {\n          const results = await Promise.allSettled(\n            cleanups.map((cleanup) => cleanup()),\n          );\n          if (results.some((result) => result.status === \"rejected\")) {\n            throw new Error(\n              \"paperclip_runner_attachment_staging_cleanup_failed\",\n            );\n          }\n        } finally {\n          releaseActiveStage();\n        }\n      },\n    };\n  } catch (error) {\n    releaseActiveStage();\n    throw error;\n  }\n}\n\nexport function renderNativeRunnerStagedAttachmentPrompt(\n  attachments: readonly NativeRunnerStagedAttachment[],\n): string {\n  if (attachments.length === 0) return \"\";","sourceCodeStart":1025,"sourceCodeEnd":1061,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/server/src/services/native-runtime/native-runner-file-handoff.ts#L1025-L1061","documentation":"Raised by the cleanup function returned from stageNativeRunnerWakeAttachments when one or more per-attachment cleanup callbacks reject after Promise.allSettled. It signals that staged attachment files could not be fully removed from the workspace staging directory, leaving residue behind.","triggerScenarios":"Calling the returned cleanup() after staging completes while at least one writeStagedAttachment cleanup fails (e.g. unlink fails because the file is locked, permissions changed, or the workspace directory was removed mid-flight).","commonSituations":"Antivirus or a file watcher holding the staged file open on Windows; workspace directory deleted while the run was executing; read-only filesystem or permission change on the staging directory; concurrent scrub racing with cleanup.","solutions":["Retry cleanup() after a short delay to let file locks release","Manually remove leftover files under the workspace's private staging directory (the per-process staging subdirectory)","Check filesystem permissions and that the workspace root still exists before rerunning the agent","Inspect logs to identify which attachment cleanup rejected and fix the underlying cause (lock, permission, missing path)"],"exampleFix":"// before\nawait staged.cleanup(); // throws cleanup_failed, residue left\n// after\ntry {\n  await staged.cleanup();\n} catch (err) {\n  if (String(err).includes(\"paperclip_runner_attachment_staging_cleanup_failed\")) {\n    await new Promise((r) => setTimeout(r, 250));\n    await staged.cleanup().catch(() => log.warn(\"staging residue remains; scrub on next run\"));\n  } else throw err;\n}","handlingStrategy":"try-catch","validationCode":"null","typeGuard":"null","tryCatchPattern":"try {\n  await staged.cleanup();\n} catch (err) {\n  if (err instanceof Error && err.message === \"paperclip_runner_attachment_staging_cleanup_failed\") {\n    // schedule retry; residue is scrubbed automatically on the next staging run in this workspace\n  } else throw err;\n}","preventionTips":["Always call cleanup() in a finally block after consuming staged attachments","Avoid holding staged files open (editors, watchers) during the run","Keep the workspace root writable for the staging process","Rely on the staging registry scrub to clean residue from prior failed cleanups"],"tags":["cleanup","filesystem","attachments","native-runtime"],"backgroundTag":"file-write-failed","analyzedSha":"3f1d897a7c018d76563a21c6e39c3c9b03933622","analyzedAt":"2026-09-18T08:03:59.046Z","contentChangedAt":"2026-09-18T08:03:59.046Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}