Skip to content

fix(ai): cap native inline file size at 50 MB to prevent V8 OOM - #19867

Open
xxiaoxiong wants to merge 5 commits into
CherryHQ:mainfrom
xxiaoxiong:fix/native-file-size-cap
Open

fix(ai): cap native inline file size at 50 MB to prevent V8 OOM#19867
xxiaoxiong wants to merge 5 commits into
CherryHQ:mainfrom
xxiaoxiong:fix/native-file-size-cap

Conversation

@xxiaoxiong

Copy link
Copy Markdown
Contributor

TL;DR

Cap the size of files inlined as base64 data: URLs at 50 MB, enforced before the read to prevent V8 heap exhaustion and app crash (SIGTRAP) when users attach ~238 MB PDFs.

Problem

fileProcessor.ts inlined every file as base64 without any size check. Base64 inflates a file by ~4/3; a 238 MB PDF becomes ~317 MB of base64, and with JSON.stringify overhead the main-process V8 heap (~2 GB on an 8 GB machine) is exhausted, leading to SIGTRAP and whole-app exits. This is #19706.

Fix

Two pre-read size guards:

  • fileEntryId branch: FileManager.getMetadata(size) called before read(encoding: base64) — prevents allocating the inflated base64 buffer for oversized files.
  • file:// URL branch: fs.stat(absPath) called before fsRead(encoding: base64) — same guard. stat follows symlinks, so symlink squatting cannot bypass the cap.

On any error (missing entry, permission denied), size is treated as Infinity so the part is degraded to a note, matching the existing failure path.

Test coverage

Updated fileProcessor.test.ts to mock FileManager.getMetadata and verify:

  • Normal-sized files pass through unchanged
  • Over-cap files return null without calling read
  • Missing/unreadable entries degrade to null (existing behaviour preserved)

References

Refuses to allocate a base64 buffer for file parts whose on-disk size
exceeds 50 MB. The previous behaviour inflated every native file by ~4/3
into the request JSON and exhausted main-process V8 heap on 8 GB
machines, leading to SIGTRAP and whole-app exits.

The cap is enforced before any read via FileManager.getMetadata (fileEntryId
branch) or fs.stat (file:// URL branch). The file:// branch uses stat
(follows symlinks) so symlink squatting cannot bypass the check by
pointing at an over-cap target. On error, the size is treated as
Infinity so the part is dropped instead of inlined.

Closes CherryHQ#19706

Signed-off-by: xxiaoxiong <2482929840@qq.com>
@xxiaoxiong
xxiaoxiong requested a review from DeJeune as a code owner September 2, 2026 04:36
Signed-off-by: xxiaoxiong <2482929840@qq.com>
Signed-off-by: xxiaoxiong <2482929840@qq.com>
…rt-sort

Signed-off-by: xxiaoxiong <2482929840@qq.com>
Signed-off-by: xxiaoxiong <2482929840@qq.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: App crash (main-process V8 OOM / SIGTRAP) when sending a ~238MB PDF to gemini-3.7-flash — no size cap on native inline attachments

1 participant