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
- Run the agent on a local execution target if it needs read_chat_attachment.
- Do not expose READ_CHAT_ATTACHMENT_TOOL_DEFINITION in the tool set for remote execution targets.
- Implement remote staging in native-runner-file-handoff if remote support is required upstream.
- 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
- Gate the read_chat_attachment tool definition on executionTargetKind === "local".
- Only create read scopes for local runs.
- Document the local-only limitation in tool listing for remote runtimes.
- Add a remote staging implementation before enabling the tool remotely.
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
- Could not clean managed GitHub launchers
- Could not prepare managed GitHub launchers
- Could not read execution-target Git context
- Could not resolve remote PATH for managed GitHub launchers
- CreateOS process stream reported an error.
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 missView on GitHub (pinned to 3f1d897a7c)