paperclipai/paperclip · error · Error
Missing delivery scope
Error message
Missing delivery scope
What it means
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.
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.
Example fix
// before
if (!storageKey) throw new Error("Missing delivery scope");
// after
if (!storageKey) {
reportTelemetry("send_blocked_missing_scope", { taskId });
throw new Error("Missing delivery scope for task " + taskId);
} Defensive patterns
Strategy: validation
Validate before calling
const key = buildStorageKey(task); if (!key) { setStorageError('Cannot determine delivery identity'); return; } Type guard
const hasScope = (k: unknown): k is string => typeof k === 'string' && k.length > 0;
Try / catch
try { writeBoardSendDraft(storageKey, input); } catch { setStorageError(STORAGE_BLOCK_MESSAGE); return; } Prevention
- 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.
When it happens
Trigger: 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).
Common situations: 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.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- [adapter-ui-loader] Failed to load UI parser for
- Add an objective after /goal to start a goal.
- Agent not found
- `}
- Discard is unavailable.
AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18).
Data as JSON: /api/errors/87e745a4e4681a83.
Report an issue: GitHub.
Appendix: source
Thrown at ui/src/components/chat/ExternallyConnectedTaskBanner.tsx:862
loadedStorageKey.current !== storageKey ||
retainedScopeKey.current !== storageKey
)
return;
idempotencyKey.current ??= crypto.randomUUID();
const input = retainedSend.current ?? {
attachmentIds: selectedAttachmentIds,
attachmentNames: selectedAttachmentIds.map((id) => ({
id,
name:
taskAttachments.find((attachment) => attachment.id === id)
?.originalFilename ?? "Unnamed attachment",
})),
body: body.trim(),
idempotencyKey: idempotencyKey.current,
publication: null,
};
try {
if (!storageKey) throw new Error("Missing delivery scope");
writeBoardSendDraft(storageKey, input);
} catch {
setStorageError(
"Browser storage could not preserve this delivery identity. No update was sent. Restore browser storage, then reload to try again.",
);
return;
}
retainedSend.current = input;
setUnconfirmedRequest(true);
publish.mutate({
...input,
endpointId: binding.endpointId,
conversationId: binding.conversationId,
});
}}
>
{publish.isPending
? "Sending…"View on GitHub (pinned to 3f1d897a7c)