paperclipai/paperclip · error

paperclip_runner_chat_attachment_remote_staging_unsupported

paperclip_runner_chat_attachment_remote_staging_unsupported

Error message

paperclip_runner_chat_attachment_remote_staging_unsupported

What it means

Staging attachment bytes into a temporary workspace path is only implemented for locally-executed runs. When the scope was constructed with executionTargetKind "remote", read() refuses immediately with this error because the workspace-file handoff cannot reach a remote execution target.

Solutions

  1. Run the agent on a local execution target if it needs read_chat_attachment.
  2. Do not expose READ_CHAT_ATTACHMENT_TOOL_DEFINITION in the tool set for remote execution targets.
  3. Implement remote staging in native-runner-file-handoff if remote support is required upstream.
  4. Route the attachment read through the remote executor's own file API as a fallback.

Example fix

// before
new NativeChatAttachmentReadScope({ ..., executionTargetKind: "remote" });
// after
new NativeChatAttachmentReadScope({ ..., executionTargetKind: "local" });
Defensive patterns

Strategy: validation

Validate before calling

if (scope.options.executionTargetKind !== "local") {
  throw new Error("read_chat_attachment requires a local execution target");
}

Type guard

function supportsAttachmentRead(scope: { options: { executionTargetKind: string } }): boolean {
  return scope.options.executionTargetKind === "local";
}

Try / catch

try {
  const file = await scope.read(input);
} catch (e) {
  if (e.message === "paperclip_runner_chat_attachment_remote_staging_unsupported") return null; // feature unavailable
  throw e;
}

Prevention

When it happens

Trigger: Calling read() on a scope whose options.executionTargetKind is "remote"; configuring the native runner with a remote execution target while still advertising the read_chat_attachment tool to the agent.

Common situations: Deploying runs to a remote sandbox/executor without porting the local staging path; a feature gap where remote runtimes were added before this tool was remote-capable.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18). Data as JSON: /api/errors/cc425e9a8a273bdf. Report an issue: GitHub.

Appendix: source

Thrown at server/src/services/native-runtime/chat-attachment-read.ts:82

    if (this.#closed)
      throw new Error("paperclip_runner_chat_attachment_read_scope_closed");
  }

  read(input: { sourceCommentId: string; attachmentId: string }) {
    this.#assertOpen();
    if (
      !UUID.test(input.sourceCommentId) ||
      !UUID.test(input.attachmentId) ||
      Object.keys(input).some(
        (key) => key !== "sourceCommentId" && key !== "attachmentId",
      )
    ) {
      throw new Error(
        "paperclip_runner_chat_attachment_read_arguments_invalid",
      );
    }
    if (this.options.executionTargetKind !== "local") {
      throw new Error(
        "paperclip_runner_chat_attachment_remote_staging_unsupported",
      );
    }
    if (++this.#readCount > 20)
      throw new Error("paperclip_runner_chat_attachment_read_limit");
    const pending = this.#read(input);
    this.#pending.add(pending);
    void pending
      .finally(() => this.#pending.delete(pending))
      .catch(() => undefined);
    return pending;
  }

  async #authorized(input: {
    sourceCommentId: string;
    attachmentId: string;
  }): Promise<ChatAttachmentReuseSource> {
    // Run-event persistence also briefly locks heartbeat_runs. A NOWAIT miss

View on GitHub (pinned to 3f1d897a7c)