tursodatabase/turso · error · Error

panic: MainWorker is not initialized

Error message

panic: MainWorker is not initialized

What it means

The bundle-variant WASM promise entry (promise-bundle.ts:8) defines init(): it awaits initThreadPool() and then requires the live-exported MainWorker from index-bundle.js to be non-null. MainWorker is assigned inside the setupMainThread callback in index-bundle.ts when the worker is created; if it is still null after initThreadPool(), the worker was never registered in this module instance. The classic cause is the bundler creating two copies of the wasm module (only the copy that ran setupMainThread got the worker) or picking an entry variant your bundler does not support.

Source

Thrown at bindings/javascript/packages/wasm/promise-bundle.ts:8

import { DatabasePromise, DatabaseOpts, SqliteError, Transaction } from "@tursodatabase/database-common"
import { registerFileAtWorker, unregisterFileAtWorker, ioNotifier } from "@tursodatabase/database-wasm-common";
import { initThreadPool, MainWorker, Database as NativeDatabase } from "./index-bundle.js";

async function init(): Promise<Worker> {
    await initThreadPool();
    if (MainWorker == null) {
        throw new Error("panic: MainWorker is not initialized");
    }
    return MainWorker;
}

class Database extends DatabasePromise {
    #worker: Worker | null;
    constructor(path: string, opts: DatabaseOpts = {}) {
        super(
            new NativeDatabase(path, opts) as unknown as any,
            () => ioNotifier.waitForCompletion(),
        )
    }
    /**
     * connect database and pre-open necessary files in the OPFS
     */
    override async connect() {
        if (!this.memory) {
            const worker = await init();

View on GitHub (pinned to 244cde92a7)

Solutions

  1. Import Database and everything else from exactly one entry point of one package copy (dedupe @tursodatabase/database-wasm in the lockfile).
  2. Call and await the entry's init() once at startup before constructing any Database.
  3. Pick the entry variant matching your bundler (e.g. promise-vite-dev-hack under Vite dev, promise-turbopack-hack under Turbopack) instead of mixing them.
  4. Ensure the worker and turso.wasm assets are served (check network tab) so setupMainThread can create the worker.
  5. Keep the module out of SSR main builds (load it lazily in the browser only).

Example fix

// before
import { Database } from "@tursodatabase/database-wasm/promise-bundle";
const db = new Database("app.db"); // module copy never initialized MainWorker

// after
import { init, Database } from "@tursodatabase/database-wasm/promise-bundle";
await init(); // worker registered in THIS module instance
const db = new Database("app.db");
Defensive patterns

Strategy: validation

Validate before calling

import { init, Database } from "@tursodatabase/database-wasm/promise-bundle";
let ready: Promise<Worker> | null = null;
export function ensureInit() {
  return (ready ??= init()); // single, awaited initialization
}
// app startup: await ensureInit(); before any new Database(...)

Try / catch

try {
  await init();
} catch (e) {
  if (e instanceof Error && /MainWorker is not initialized/.test(e.message)) {
    // module duplication or failed worker spawn: dedupe entries / check network for worker.js + turso.wasm
  } else throw e;
}

Prevention

When it happens

Trigger: Importing the database from one module instance while another duplicate copy (created by bundler resolution) ran setupMainThread; mixing entry files (index-bundle.js, index-default.js, hack variants) in one app; calling Database before the module's top-level await (fetch of turso.wasm + setupMainThread) completed in the copy you imported; worker script failing to load so the callback never assigned MainWorker.

Common situations: Webpack/rollup-style setups where '#index' or subpath imports resolve to two physical files; monorepos with duplicate @tursodatabase/database-wasm versions; SSR frameworks evaluating the module on the server where Worker is unavailable; using the bundle variant with a bundler that needs the vite/turbopack hack variant instead.

Related errors


AI-assisted analysis of tursodatabase/turso@244cde92a7 (2026-08-20). Data as JSON: /api/errors/34ae6d7da32a8e28. Report an issue: GitHub.