Skip to content

fix(sandbox): cap task timer bridges and dispose isolates on host timeout - #9776

Merged
waleedlatif1 merged 3 commits into
stagingfrom
fix/ivm-task-timer-cap
Nov 7, 2026
Merged

waleedlatif1 merged 3 commits into
stagingfrom
fix/ivm-task-timer-cap

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

  • Task-mode setTimeout/setInterval bridges in the isolated-vm worker kept a Node Timeout, a Map entry, and an ivm.Reference per call on the shared worker heap with no count limit — outside the isolate's 128 MB memoryLimit. One document-generation or workflow-test script could grow worker RSS without bound or starve the worker's event loop for every co-tenant execution on it
  • Cap each task execution at 1000 pending timers and 50 active intervals; the bridge throws a RangeError back into the isolate (no host frames in the stack) and releases the callback reference
  • On host timeout, send the existing cancel IPC to the worker. A never-settling promise escapes isolated-vm's script timeout, so the worker kept the isolate (and its live intervals) running until the worker retired — on both the task and Function-block paths
  • Skipped the suggested interval period floor and firing-count cap: zero-delay setTimeout chains already reach the same rate, so the floor only changes behavior for legitimate setInterval(fn, 1) callers

Type of Change

  • Bug fix (security)

Testing

Verified against the real worker process before and after (scratch harness that forks isolated-vm-worker.cjs over IPC):

  • Before: for (...) setTimeout(f, 60000) grew worker RSS ~80 MB/s, past 2.5 GB at 30s, well beyond the script timeout. 20k setInterval(f, 1) starved the worker — 20 trivial co-tenant executions did not finish within 60s
  • After: the flood stops at the cap in <100ms; co-tenant latency median 4ms / max 6ms under the interval flood, 3ms / 3ms under the worst load the caps allow (1000 zero-delay chains + 50 intervals), same as idle
  • Hung task with a busy interval, local pool: worker CPU in the 3s after timeout went from 2060ms to 0ms; the worker keeps serving
  • Reverted each guard separately (timeout cap, interval cap, interval decrement on clear) and watched its case go red
  • Real docx-generate (2000 paragraphs), pptx-generate (200 slides, JSZip setImmediate chains), pdf-generate (200 pages) through runSandboxTask: valid output, timings unchanged vs staging
  • New isolated-vm.test.ts case (host sends cancel on timeout) red before / green after; isolated-vm.test.ts + isolated-vm-worker-hardening.test.ts 28/28
  • test-isolated-vm-remote-e2e.ts: new check "caps the timers a task may hold on the shared worker"; all 21 checks pass, new check fails on the staging worker
  • biome, check:test-patterns, check:comment-hygiene, check:utils, check:boundaries; full gate left to CI

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing (new tests pass the test-audit authoring gate)
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

🤖 Generated with Claude Code

@vercel

vercel Bot commented Nov 7, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
docs Skipped Skipped Nov 7, 2026 8:24pm UTC

Request Review

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues found across 4 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Turn on auto-fix | Re-trigger cubic

@greptile-apps

greptile-apps Bot commented Nov 7, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no new actionable issues were found.

Summary

The PR caps task timers and asks the worker to stop an execution when the host timeout fires.

  • Each task stops at 1,000 pending timers or 50 active intervals.
  • Host timeouts now ask the worker to dispose the timed-out isolate.

Reviews (2) · Last reviewed commit: "improvement(sandbox): cover interval reu..." · Reviewed by Greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Nov 7, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai review this PR

@waleedlatif1 I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues found across 4 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Turn on auto-fix | Re-trigger cubic

@waleedlatif1
waleedlatif1 merged commit 63487f7 into staging Nov 7, 2026
61 checks passed
@waleedlatif1
waleedlatif1 deleted the fix/ivm-task-timer-cap branch November 7, 2026 20:27

This branch was previously deployed

1 inactive deployment
Preview — 4287ab28 Deployed Nov 7, 2026 by vercel[bot]
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.

1 participant