Skip to content

fix(rivetkit): lazy-load agent-os-core to avoid node:sqlite crash on Bun#4550

Draft
brittianwarner wants to merge 2 commits intomainfrom
fix/agent-os-lazy-load-core
Draft

fix(rivetkit): lazy-load agent-os-core to avoid node:sqlite crash on Bun#4550
brittianwarner wants to merge 2 commits intomainfrom
fix/agent-os-lazy-load-core

Conversation

@brittianwarner
Copy link
Copy Markdown

@brittianwarner brittianwarner commented Apr 3, 2026

Summary

  • Lazy-loads @rivet-dev/agent-os-core at runtime instead of importing eagerly at module level
  • Prevents require("node:sqlite") side-effect from crashing on runtimes that lack it (e.g. Bun)
  • Uses Array.join() specifier trick to prevent Turbopack from tracing into the module graph at compile time (same technique as sqlite-pool.ts)
  • Clears the cached import promise on failure so subsequent calls retry instead of returning a permanently rejected promise

Changes

  • agent-os/actor/index.ts: Convert AgentOs and createInMemoryFileSystem from static imports to lazy dynamic imports via loadAgentOsCore()
  • buildVmOptions() now receives createMemFs as a parameter instead of importing it at the top level

@railway-app
Copy link
Copy Markdown

railway-app bot commented Apr 3, 2026

This PR was not deployed automatically as @brittianwarner does not have access to the Railway project.

In order to get automatic PR deploys, please add @brittianwarner to your workspace on Railway.

Copy link
Copy Markdown
Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Apr 3, 2026

More templates

@rivetkit/cloudflare-workers

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/cloudflare-workers@4550

@rivetkit/framework-base

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/framework-base@4550

@rivetkit/next-js

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/next-js@4550

@rivetkit/react

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/react@4550

rivetkit

pnpm add https://pkg.pr.new/rivet-dev/rivet/rivetkit@4550

@rivetkit/sql-loader

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/sql-loader@4550

@rivetkit/sqlite-vfs

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/sqlite-vfs@4550

@rivetkit/traces

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/traces@4550

@rivetkit/workflow-engine

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/workflow-engine@4550

@rivetkit/virtual-websocket

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/virtual-websocket@4550

@rivetkit/engine-runner

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/engine-runner@4550

@rivetkit/engine-runner-protocol

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/engine-runner-protocol@4550

commit: 90e7817

@claude
Copy link
Copy Markdown

claude bot commented Apr 3, 2026

PR Review: fix(rivetkit) lazy-load agent-os-core

Overall: Well-targeted, minimal fix. Consistent with the sqlite-pool.ts pattern. A few items to address before merge.

Positive:

  • The Array.join() specifier trick matches sqlite-pool.ts:29 pattern, maintaining consistency
  • All value imports in src/agent-os/ correctly converted to import type
  • CreateMemFs type alias keeps buildVmOptions signature readable
  • Retry-on-failure: agentOsCorePromise = null in .catch before re-throwing is correct

Issues:

BUG (low-impact): Race condition in loadAgentOsCore during concurrent calls
File: src/agent-os/actor/index.ts, lines 49-67

When two concurrent callers hit loadAgentOsCore() before the first import() resolves, both pass the null guard and create separate import(specifier) calls. The second assignment wins agentOsCorePromise, but both .catch handlers race to write agentOsCorePromise = null on failure. The dropped import() call can produce an unhandled promise rejection.

Fix: Assign agentOsCorePromise to the full promise chain (including .catch) synchronously in one step before any await point, matching the sqlite-pool.ts approach. This closes the concurrent-caller race window.

MINOR: No test coverage for the Bun import-safety guarantee
No tests verify that importing rivetkit/agent-os does not throw at import time when @rivet-dev/agent-os-core is unavailable. Existing actor-agent-os.ts driver tests cover the Node.js happy path only. Worth tracking.

Summary:

  • Bug (low-impact): Race condition, promise assigned after import() call not atomically (actor/index.ts:54-59)
  • Minor: No Bun import-safety test coverage
  • Positive: All value imports correctly converted to import type
  • Positive: Pattern consistent with sqlite-pool.ts
  • Positive: Retry-on-failure correctly implemented

The core approach is correct. Main change before merging: fix assignment order so agentOsCorePromise is set synchronously before any await point.

Copy link
Copy Markdown
Author

@NathanFlurry This is addition to #1428

Wrap loadAgentOsCore rejection with a descriptive error message and
cause chain. Extract CreateMemFs type alias to clean up the verbose
inline typeof import parameter on buildVmOptions.
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