diff --git a/src/core/mentions/index.ts b/src/core/mentions/index.ts
index d0d305d096..881c2cc292 100644
--- a/src/core/mentions/index.ts
+++ b/src/core/mentions/index.ts
@@ -267,11 +267,18 @@ async function getFileOrFolderContent(
const absoluteFilePath = path.resolve(absPath, entry.name)
fileContentPromises.push(
(async () => {
+ let isBinary = false
+ try {
+ isBinary = await isBinaryFile(absoluteFilePath)
+ } catch (error) {
+ // If isBinaryFile throws an error (e.g., RangeError), treat as binary
+ console.warn(`Error checking if file is binary for ${absoluteFilePath}:`, error)
+ isBinary = true
+ }
+ if (isBinary) {
+ return undefined
+ }
try {
- const isBinary = await isBinaryFile(absoluteFilePath).catch(() => false)
- if (isBinary) {
- return undefined
- }
const content = await extractTextFromFile(absoluteFilePath, maxReadFileLine)
return `\n${content}\n`
} catch (error) {
diff --git a/src/core/tools/__tests__/readFileTool.spec.ts b/src/core/tools/__tests__/readFileTool.spec.ts
index 44be1d3b92..ab7e69eee7 100644
--- a/src/core/tools/__tests__/readFileTool.spec.ts
+++ b/src/core/tools/__tests__/readFileTool.spec.ts
@@ -518,5 +518,26 @@ describe("read_file tool XML output structure", () => {
`\n${testFilePath}Access to ${testFilePath} is blocked by the .rooignore file settings. You must try to continue in the task without using this file, or ask the user to update the .rooignore file.\n`,
)
})
+
+ it("should handle RangeError from isBinaryFile gracefully", async () => {
+ // Setup - mock isBinaryFile to throw RangeError
+ mockedIsBinaryFile.mockRejectedValue(new RangeError("Invalid array length"))
+ mockedCountFileLines.mockResolvedValue(5)
+
+ // Execute - the main goal is to verify the error doesn't crash the application
+ const result = await executeReadFileTool(
+ {},
+ {
+ totalLines: 5,
+ },
+ )
+
+ // Verify that the file is processed (the error is handled gracefully)
+ expect(result).toContain(`${testFilePath}`)
+
+ // Verify that we get a valid XML response (not an error)
+ expect(result).toMatch(/.*<\/files>/s)
+ expect(result).not.toContain("")
+ })
})
})
diff --git a/src/core/tools/readFileTool.ts b/src/core/tools/readFileTool.ts
index 6de8dd5642..b8d3f8989c 100644
--- a/src/core/tools/readFileTool.ts
+++ b/src/core/tools/readFileTool.ts
@@ -433,7 +433,20 @@ export async function readFileTool(
// Process approved files
try {
- const [totalLines, isBinary] = await Promise.all([countFileLines(fullPath), isBinaryFile(fullPath)])
+ let totalLines: number
+ let isBinary: boolean
+
+ // First, count the file lines (this should not fail for valid files)
+ totalLines = await countFileLines(fullPath)
+
+ // Then check if it's binary, with error handling specific to isBinaryFile
+ try {
+ isBinary = await isBinaryFile(fullPath)
+ } catch (error) {
+ // If isBinaryFile throws an error (e.g., RangeError), treat the file as binary
+ console.warn(`Error checking if file is binary for ${relPath}:`, error)
+ isBinary = true
+ }
// Handle binary files (but allow specific file types that extractTextFromFile can handle)
if (isBinary) {
diff --git a/src/integrations/misc/__tests__/extract-text-large-files.spec.ts b/src/integrations/misc/__tests__/extract-text-large-files.spec.ts
index fc2f7f54b6..e164c070ab 100644
--- a/src/integrations/misc/__tests__/extract-text-large-files.spec.ts
+++ b/src/integrations/misc/__tests__/extract-text-large-files.spec.ts
@@ -25,6 +25,8 @@ describe("extractTextFromFile - Large File Handling", () => {
// Set default mock behavior
mockedFs.access.mockResolvedValue(undefined)
mockedIsBinaryFile.mockResolvedValue(false)
+ // Mock console.warn
+ vi.spyOn(console, "warn").mockImplementation(() => {})
})
it("should truncate files that exceed maxReadFileLine limit", async () => {
@@ -218,4 +220,20 @@ describe("extractTextFromFile - Large File Handling", () => {
"File not found: /test/nonexistent.ts",
)
})
+
+ it("should handle RangeError from isBinaryFile and treat file as binary", async () => {
+ // Setup - mock isBinaryFile to throw RangeError
+ mockedIsBinaryFile.mockRejectedValue(new RangeError("Invalid array length"))
+
+ // Execute and expect it to throw since file is treated as binary
+ await expect(extractTextFromFile("/test/problematic-file.bin", 100)).rejects.toThrow(
+ "Cannot read text for file type: .bin",
+ )
+
+ // Verify that the warning was logged
+ expect(console.warn).toHaveBeenCalledWith(
+ "Error checking if file is binary for /test/problematic-file.bin:",
+ expect.any(RangeError),
+ )
+ })
})
diff --git a/src/integrations/misc/extract-text.ts b/src/integrations/misc/extract-text.ts
index 8231c609be..a2a9c722ee 100644
--- a/src/integrations/misc/extract-text.ts
+++ b/src/integrations/misc/extract-text.ts
@@ -86,7 +86,14 @@ export async function extractTextFromFile(filePath: string, maxReadFileLine?: nu
}
// Handle other files
- const isBinary = await isBinaryFile(filePath).catch(() => false)
+ let isBinary = false
+ try {
+ isBinary = await isBinaryFile(filePath)
+ } catch (error) {
+ // If isBinaryFile throws an error (e.g., RangeError), treat as binary
+ console.warn(`Error checking if file is binary for ${filePath}:`, error)
+ isBinary = true
+ }
if (!isBinary) {
// Check if we need to apply line limit