{"record":{"id":"87e745a4e4681a83","repo":"paperclipai/paperclip","slug":"missing-delivery-scope","errorCode":null,"errorMessage":"Missing delivery scope","messagePattern":"Missing delivery scope","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ui/src/components/chat/ExternallyConnectedTaskBanner.tsx","lineNumber":862,"sourceCode":"                  loadedStorageKey.current !== storageKey ||\n                  retainedScopeKey.current !== storageKey\n                )\n                  return;\n                idempotencyKey.current ??= crypto.randomUUID();\n                const input = retainedSend.current ?? {\n                  attachmentIds: selectedAttachmentIds,\n                  attachmentNames: selectedAttachmentIds.map((id) => ({\n                    id,\n                    name:\n                      taskAttachments.find((attachment) => attachment.id === id)\n                        ?.originalFilename ?? \"Unnamed attachment\",\n                  })),\n                  body: body.trim(),\n                  idempotencyKey: idempotencyKey.current,\n                  publication: null,\n                };\n                try {\n                  if (!storageKey) throw new Error(\"Missing delivery scope\");\n                  writeBoardSendDraft(storageKey, input);\n                } catch {\n                  setStorageError(\n                    \"Browser storage could not preserve this delivery identity. No update was sent. Restore browser storage, then reload to try again.\",\n                  );\n                  return;\n                }\n                retainedSend.current = input;\n                setUnconfirmedRequest(true);\n                publish.mutate({\n                  ...input,\n                  endpointId: binding.endpointId,\n                  conversationId: binding.conversationId,\n                });\n              }}\n            >\n              {publish.isPending\n                ? \"Sending…\"","sourceCodeStart":844,"sourceCodeEnd":880,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/ui/src/components/chat/ExternallyConnectedTaskBanner.tsx#L844-L880","documentation":"ConnectedTaskComposer persists the outbound delivery identity (to/channel/publication metadata) via `writeBoardSendDraft(storageKey, input)`. The `storageKey` derives from the delivery scope of the task; if it is missing, the composer cannot safely persist the send identity, throws, and blocks the send with a storage-error banner telling the user nothing was sent.","triggerScenarios":"Submitting an externally connected task update when the computed `storageKey` is empty — e.g. the task lacks the connected-channel identifiers used to build the key (no publication/channel/to address binding).","commonSituations":"Task connected to a channel whose external identity was removed or re-keyed; localStorage access context changed (different origin/incognito) so the scope key could not be derived; partial hydration of connected-task props.","solutions":["Verify the task's external connection binding (channel/publication ids) is intact; re-connect the task to its channel.","Check the code computing `storageKey` — log why it is empty (missing connectedChannelId vs to address).","Clear the stale banner state via reload after restoring the connection, then retry the send."],"exampleFix":"// before\nif (!storageKey) throw new Error(\"Missing delivery scope\");\n// after\nif (!storageKey) {\n  reportTelemetry(\"send_blocked_missing_scope\", { taskId });\n  throw new Error(\"Missing delivery scope for task \" + taskId);\n}","handlingStrategy":"validation","validationCode":"const key = buildStorageKey(task); if (!key) { setStorageError('Cannot determine delivery identity'); return; }","typeGuard":"const hasScope = (k: unknown): k is string => typeof k === 'string' && k.length > 0;","tryCatchPattern":"try { writeBoardSendDraft(storageKey, input); } catch { setStorageError(STORAGE_BLOCK_MESSAGE); return; }","preventionTips":["Verify connected-task channel/publication bindings before enabling send.","Log which identifier is missing when the key cannot be built.","Re-connect tasks whose external channel identity changed."],"tags":["storage","send-flow","ui"],"backgroundTag":"missing-required-config-field","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"}