Skip to content

fix: support exporting recordings larger than 2 GiB#520

Open
TafadzwaD wants to merge 2 commits into
webadderallorg:mainfrom
TafadzwaD:fix/large-file-export-err-fs-file-too-large
Open

fix: support exporting recordings larger than 2 GiB#520
TafadzwaD wants to merge 2 commits into
webadderallorg:mainfrom
TafadzwaD:fix/large-file-export-err-fs-file-too-large

Conversation

@TafadzwaD
Copy link
Copy Markdown

@TafadzwaD TafadzwaD commented May 16, 2026

Description

Export fails with RangeError [ERR_FS_FILE_TOO_LARGE] when the source recording exceeds 2 GiB. The read-local-file IPC handler used fs.readFile, which has a hard ~2 GiB limit in Node.js. This caused both legacy and Lightning (Beta) exports of long recordings to fail.

Motivation

Users recording tutorials commonly produce recordings over 2 GiB. The error was unrecoverable — there was no fallback and the export dialog showed a cryptic range error with no guidance.

Type of Change

  • New Feature
  • Bug Fix
  • Refactor / Code Cleanup
  • Documentation Update
  • Other (please specify)

Related Issue(s)

#493

Screenshots / Video

Error before fix:

image

Testing Guide

  1. Record or source a video file larger than 2 GiB
  2. Open it in the editor and start an export (both legacy and Lightning paths)
  3. Confirm the export completes without ERR_FS_FILE_TOO_LARGE
  4. Also confirm a normal (<2 GiB) recording still exports correctly (no regression)

Checklist

  • I have performed a self-review of my code.
  • I have added any necessary screenshots or videos.
  • I have linked related issue(s) and updated the changelog if applicable.

Node.js fs.readFile throws ERR_FS_FILE_TOO_LARGE for files >2 GiB.
The read-local-file IPC handler used readFile, causing exports to fail
when the source recording exceeded that limit.

Replace readFile with fileHandle.read in 64 MiB chunks — no size limit.
Also change createReadableMediaResourceFile to fall through to URL-based
fetch when readLocalFile fails, rather than throwing immediately.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 16, 2026

📝 Walkthrough

Walkthrough

Chunked-reading replaces single-call fs.readFile in the Electron IPC handler (reads in 64 MiB segments, returns {success,data} or {success:false,error}), and the renderer consumes that result to create a File on success or fall back to URL+fetch on failure.

Changes

Large file handling with fallback

Layer / File(s) Summary
Chunked file reading IPC handler
electron/ipc/register/assets.ts
read-local-file replaces fs.readFile() with fs.open(), fs.stat(), allocates a Buffer, reads in 64 MiB segments via FileHandle.read() until EOF, closes the handle in finally, and returns {success: true, data: buffer} or {success: false, error: String(error)}.
Fallback media resource file creation
src/lib/exporter/localMediaSource.ts
createReadableMediaResourceFile now constructs and returns a File only when result.success is true and result.data is present; on failure or missing data it falls through to resolveMediaResourceUrl + fetch instead of throwing.

Sequence Diagram(s)

sequenceDiagram
  participant Renderer
  participant IPC_Handler
  participant FileSystem
  participant Network
  Renderer->>IPC_Handler: readLocalFile(path)
  IPC_Handler->>FileSystem: fs.open(resolved)
  FileSystem-->>IPC_Handler: fileHandle
  IPC_Handler->>FileSystem: fs.stat(resolved)
  FileSystem-->>IPC_Handler: size
  IPC_Handler->>IPC_Handler: allocate Buffer(size)
  loop Read 64 MiB chunks
    IPC_Handler->>FileSystem: fileHandle.read(buffer, offset, chunkSize)
    FileSystem-->>IPC_Handler: bytesRead
  end
  IPC_Handler->>FileSystem: fileHandle.close()
  alt Success
    IPC_Handler-->>Renderer: {success: true, data: buffer}
    Renderer->>Renderer: create File from Buffer
  else Failure
    IPC_Handler-->>Renderer: {success: false, error}
    Renderer->>Network: resolveMediaResourceUrl + fetch(url)
    Network-->>Renderer: Response -> create File
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • webadderallorg/Recordly#419: Modifies the same read-local-file IPC handler to update authorization checks, complementary to this chunked reading refactor.

Poem

🐰
In buffered hops I read the stream,
Big files no longer break my dream.
If local fails, I fetch the sky,
A gentle fallback, swift and spry.
Exports safe — a rabbit's sigh.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: supporting export of recordings larger than 2 GiB, which directly addresses the core issue being fixed.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The pull request description is well-structured, following the template with all required sections completed including description, motivation, type of change, related issue link, testing guide, and checklist.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@electron/ipc/register/assets.ts`:
- Around line 124-134: The code uses Buffer.allocUnsafe(fileSize) and may return
uninitialized tail bytes if the file is truncated (fileHandle.stat() -> fileSize
then reads fewer bytes), so change the return to only include the bytes actually
read: after the read loop return the buffer trimmed to offset (e.g., use
buffer.slice(0, offset) or similar), referencing fileHandle, stat, fileSize,
buffer, offset and bytesRead to locate the logic; this preserves the performance
advantage of allocUnsafe while ensuring no uninitialized memory is exposed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: c8517073-efae-43b9-ac43-9dad5dddbe44

📥 Commits

Reviewing files that changed from the base of the PR and between 6255890 and 5539fd6.

📒 Files selected for processing (2)
  • electron/ipc/register/assets.ts
  • src/lib/exporter/localMediaSource.ts

Comment thread electron/ipc/register/assets.ts Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant