{"record":{"id":"2cd2b9ceb7f56b0c","repo":"paperclipai/paperclip","slug":"this-attachment-has-no-matching-verified-publication-receipt","errorCode":null,"errorMessage":"This attachment has no matching verified publication receipt for this run's requested output. Inspect any preserved file and use register_deliverable to verify its current filename, size, and SHA-256, then cite the new receipt. No human completion approval was created.","messagePattern":"This attachment has no matching verified publication receipt for this run's requested output\\. Inspect any preserved file and use register_deliverable to verify its current filename, size, and SHA-256, then cite the new receipt\\. No human completion approval was created\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/src/services/native-runtime/native-deliverable-feedback.ts","lineNumber":124,"sourceCode":"      const id = attachmentPath?.[1] ?? ref.slice(\"deliverable:\".length);\n      const uuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/iu;\n      const [attachment] = uuid.test(id)\n        ? await db.select({ id: issueAttachments.id, originatingRunId: issueAttachments.originatingRunId,\n            filename: assets.originalFilename, byteSize: assets.byteSize, sha256: assets.sha256 }).from(issueAttachments)\n            .innerJoin(assets, and(eq(assets.id, issueAttachments.assetId), eq(assets.companyId, binding.companyId)))\n            .where(and(eq(issueAttachments.id, id), eq(issueAttachments.companyId, binding.companyId), eq(issueAttachments.issueId, binding.issueId)))\n            .limit(1)\n        : [];\n      if (!attachment) {\n        throw new Error(\"Completion cites no registered attachment on this task. Use register_deliverable for the requested file and cite deliverable:<attachmentId> from its receipt. No human completion approval was created.\");\n      }\n      // A prior output (or user input) can be useful context, but does not prove\n      // this run published the newly requested output. The receipt survives a\n      // controller restart of this run; a replacement can re-register preserved\n      // workspace bytes internally rather than asking the user to confirm them.\n      if (fileRequested && attachment.originatingRunId !== binding.runId) continue;\n      if (fileRequested && !await hasCurrentPublicationReceipt(db, binding.companyId, binding.semanticToolReceipts, attachment)) {\n        throw new Error(\"This attachment has no matching verified publication receipt for this run's requested output. Inspect any preserved file and use register_deliverable to verify its current filename, size, and SHA-256, then cite the new receipt. No human completion approval was created.\");\n      }\n      registeredAttachment = true;\n      continue;\n    }\n    // URLs and typed durable refs are not workspace paths. Verification commands\n    // belong in verification; do not scan prose or upload files named by a model.\n    const localFile = /^(?:file:|\\.{0,2}\\/|[a-z]:[\\\\/])/iu.test(ref)\n      || (!/^[a-z][a-z0-9+.-]*:/iu.test(ref) && /^[^\\r\\n]+\\.[a-z0-9]{1,16}(?::\\d+(?::\\d+)?)?$/iu.test(ref));\n    if (localFile && (fileRequested || artifactRefs.has(value))) {\n      throw new Error(\"Completion cites a workspace-only file that the user cannot download. Before finishing, use register_deliverable for requested file outputs and cite deliverable:<attachmentId> from the receipt, with /api/attachments/<attachmentId>/content as the download link. For repository changes, cite an accessible PR or registered work product instead. No human completion approval was created.\");\n    }\n  }\n  if (fileRequested && !registeredAttachment) {\n    const products = refs.size ? await db.select().from(issueWorkProducts).where(and(\n      eq(issueWorkProducts.companyId, binding.companyId), eq(issueWorkProducts.issueId, binding.issueId),\n    )) : [];\n    const accessibleProduct = products.some(product => {\n      if (product.createdByRunId !== binding.runId) return false;","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/server/src/services/native-runtime/native-deliverable-feedback.ts#L106-L142","documentation":"A cited attachment exists on the task, but for a newly requested file output the runtime also requires a current publication receipt matching that attachment's filename, byte size, and SHA-256 (hasCurrentPublicationReceipt) originating from this run. Prior-run or user-uploaded bytes are explicitly not proof that this run published the requested output, so the evidence is rejected.","triggerScenarios":"validateNativeDeliverableEvidence with fileRequested=true and an attachment whose originatingRunId !== binding.runId (skipped via continue, leaving no registeredAttachment), or whose stored bytes no longer match a receipt from this run (filename/size/sha256 changed).","commonSituations":"Citing an attachment produced by an earlier run or uploaded by the user; workspace file was regenerated with different bytes after register_deliverable; controller restart cleared receipts so re-verification is needed.","solutions":["Inspect the preserved file in the workspace and call register_deliverable again to verify its current filename, size, and SHA-256","Cite the NEW deliverable:<attachmentId> from the fresh receipt in the completion report","If the original bytes are gone, regenerate the output, register it, and cite that receipt"],"exampleFix":"// before\nDeliverable: deliverable:<attachment-from-prior-run>\n// after\nregister_deliverable(file) -> receipt -> \"Deliverable: deliverable:<new-attachment-id>\"","handlingStrategy":"validation","validationCode":"const receiptOk = receipts.some(r => r.attachmentId === citedId && r.originatingRunId === currentRunId && r.sha256 === currentFileSha256);\nif (!receiptOk) await registerDeliverable(file); // re-verify and cite the new receipt","typeGuard":"const currentRunReceipt = (r, runId) => r.originatingRunId === runId && r.sha256 != null;","tryCatchPattern":"try { await feedback(payload); } catch (e) { if (e.message.includes(\"no matching verified publication receipt\")) { await registerDeliverable(file); /* update citation to new receipt */ } else throw e; }","preventionTips":["After any file regeneration, re-run register_deliverable — old receipts are invalidated by changed bytes","Only cite attachments produced by the current run, not prior runs or user uploads","Store the sha256 from your own register_deliverable call to self-verify before citing"],"tags":["deliverables","checksum","receipts"],"backgroundTag":"checksum-mismatch","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"}