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

  1. Verify the task's external connection binding (channel/publication ids) is intact; re-connect the task to its channel.
  2. Check the code computing `storageKey` — log why it is empty (missing connectedChannelId vs to address).
  3. 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

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


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)