paperclipai/paperclip · error
paperclip_runner_chat_attachment_read_arguments_invalid
paperclip_runner_chat_attachment_read_arguments_invalid
Error message
paperclip_runner_chat_attachment_read_arguments_invalid
What it means
read() validates its input strictly before doing any work: both sourceCommentId and attachmentId must be UUID-shaped strings, and the input object may contain no extra keys (additionalProperties false). Any violation throws this error synchronously. It is a pre-flight guard for the read_chat_attachment tool contract.
Solutions
- Obtain both ids verbatim from the list_chat_attachments tool output; never construct them by hand.
- Validate UUID format before calling read().
- Strip any extra keys from the input object; only sourceCommentId and attachmentId are accepted.
- If a new parameter is needed, update READ_CHAT_ATTACHMENT_TOOL_DEFINITION's inputSchema and this check together.
Example fix
// before
await scope.read({ sourceCommentId: "42", attachmentId: id, path: "./file" });
// after
await scope.read({ sourceCommentId: "9f0c...-uuid", attachmentId: "2ab1...-uuid" }); Defensive patterns
Strategy: validation
Validate before calling
const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
function canRead(input) {
return input != null
&& UUID.test(String(input.sourceCommentId))
&& UUID.test(String(input.attachmentId))
&& Object.keys(input).every(k => k === "sourceCommentId" || k === "attachmentId");
} Type guard
function isValidReadInput(input: unknown): input is { sourceCommentId: string; attachmentId: string } {
const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
if (typeof input !== "object" || input === null) return false;
const o = input as Record<string, unknown>;
return typeof o.sourceCommentId === "string" && UUID.test(o.sourceCommentId)
&& typeof o.attachmentId === "string" && UUID.test(o.attachmentId)
&& Object.keys(o).length === 2;
} Try / catch
try {
const file = await scope.read(input);
} catch (e) {
if (e.message === "paperclip_runner_chat_attachment_read_arguments_invalid") return { status: "bad_tool_arguments" };
throw e;
} Prevention
- Copy ids verbatim from list_chat_attachments output.
- Validate tool arguments against the JSON schema before dispatching.
- Never add fields to the tool input without updating the schema and validator together.
- Sanitize model-generated tool calls with a strict parser.
When it happens
Trigger: Calling read() with a non-UUID or empty sourceCommentId/attachmentId; passing extra properties in the input object (e.g. a guessed 'path' or 'commentId' key); passing null/undefined/numeric ids; a model emitting malformed tool arguments.
Common situations: An LLM hallucinating tool arguments that don't match the JSON schema; hand-rolled tool calls using display ids instead of the UUIDs returned by list_chat_attachments; adding a new input field without updating the schema.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- --api-key-secret-id must be a UUID
- External chat attachment ids must be UUIDs
- Name the reviewer's exact agent ID in targetAgentId.
- A full lowercase source SHA is required.
- A reusable lease cannot be replaced and reacquired in the…
AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18).
Data as JSON: /api/errors/436347ea0b63f349.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/services/native-runtime/chat-attachment-read.ts:77
storageTimeoutMs?: number;
},
) {}
#assertOpen() {
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;
}
View on GitHub (pinned to 3f1d897a7c)