Skip to content

Commit aee30ca

Browse files
committed
computer: Recognize message-only missing media
1 parent ea27af1 commit aee30ca

2 files changed

Lines changed: 41 additions & 4 deletions

File tree

packages/computer/src/tools/ai.test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,6 +1094,42 @@ describe("createAITools filesystem tools", () => {
10941094
});
10951095
});
10961096

1097+
it("recognizes message-only missing media errors", async () => {
1098+
const store = memoryStore({ size: 2 });
1099+
store.readChunks = () => ({
1100+
[Symbol.asyncIterator]() {
1101+
return this;
1102+
},
1103+
async next(): Promise<IteratorResult<Uint8Array>> {
1104+
throw new Error("ENOENT: no such file or directory");
1105+
},
1106+
});
1107+
const tool = createReadTool({ store, maxModelBytes: 4 });
1108+
const output = await executeTool(tool, { path: "/workspace/image.png" });
1109+
1110+
await expect(modelOutput(tool, { path: "/workspace/image.png" }, output)).resolves.toEqual({
1111+
type: "error-text",
1112+
value: "Could not read file bytes: /workspace/image.png",
1113+
});
1114+
});
1115+
1116+
it("does not confuse unrelated no-such errors with missing media", async () => {
1117+
const failure = new Error("SQLITE_ERROR: no such table: vfs_chunks");
1118+
const store = memoryStore({ size: 2 });
1119+
store.readChunks = () => ({
1120+
[Symbol.asyncIterator]() {
1121+
return this;
1122+
},
1123+
async next(): Promise<IteratorResult<Uint8Array>> {
1124+
throw failure;
1125+
},
1126+
});
1127+
const tool = createReadTool({ store, maxModelBytes: 4 });
1128+
const output = await executeTool(tool, { path: "/workspace/image.png" });
1129+
1130+
await expect(modelOutput(tool, { path: "/workspace/image.png" }, output)).rejects.toBe(failure);
1131+
});
1132+
10971133
it("does not hide unrelated inline media read failures", async () => {
10981134
const failure = new Error("storage unavailable");
10991135
const store = memoryStore({ size: 2 });

packages/computer/src/tools/fs/read.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -313,11 +313,12 @@ function validateBoundedReadLimit(name: string, value: number): number {
313313
}
314314

315315
function isMissingFileError(error: unknown): boolean {
316+
if (error === null || typeof error !== "object") return false;
317+
const candidate = error as { code?: unknown; message?: unknown };
318+
if (candidate.code === "ENOENT") return true;
316319
return (
317-
error !== null &&
318-
typeof error === "object" &&
319-
"code" in error &&
320-
(error as { code?: unknown }).code === "ENOENT"
320+
typeof candidate.message === "string" &&
321+
(/\bENOENT\b/i.test(candidate.message) || /no such (?:file|path)\b/i.test(candidate.message))
321322
);
322323
}
323324

0 commit comments

Comments
 (0)