tursodatabase/turso · error · Error
method ${name} must be invoked only from the main thread
Error message
method ${name} must be invoked only from the main thread What it means
panicWorker() in wasm-common/index.ts is the mirror guard of panicMain: the worker-side import object routes methods that only the main thread may execute (async OPFS completion paths and friends) to this throw. If the worker-side shim is invoked on the main thread, the module/imports were wired to the wrong context - normally worker and main import sets are installed in their respective realms by setupMainThread/worker setup. The error therefore indicates main-thread code executing a worker-only import.
Source
Thrown at bindings/javascript/packages/wasm-common/index.ts:42
is_web_worker(): boolean;
lookup_file(ptr: number, len: number): number;
read(handle: number, ptr: number, len: number, offset: number): number;
read_async(handle: number, ptr: number, len: number, offset: number, c: number);
write(handle: number, ptr: number, len: number, offset: number): number;
write_async(handle: number, ptr: number, len: number, offset: number, c: number);
sync(handle: number): number;
sync_async(handle: number, c: number);
truncate(handle: number, len: number): number;
truncate_async(handle: number, len: number, c: number);
size(handle: number): number;
}
function panicMain(name): never {
throw new Error(`method ${name} must be invoked only from the worker thread`);
}
function panicWorker(name): never {
throw new Error(`method ${name} must be invoked only from the main thread`);
}
function mainImports(worker: Worker, completeOpfs: (c: any, r: any) => void): BrowserImports {
return {
is_web_worker(): boolean {
return false;
},
write_async(handle, ptr, len, offset, c) {
writeFileAtWorker(worker, handle, ptr, len, offset)
.then(result => {
completeOpfs(c, result);
}, err => {
console.error('write_async', err);
completeOpfs(c, -1);
});
},
sync_async(handle, c) {
syncFileAtWorker(worker, handle)View on GitHub (pinned to 244cde92a7)
Solutions
- Use the package's official entry points so worker imports are only installed inside the spawned worker.
- Disable worker inlining/single-file transforms for the turso worker chunk in your bundler config.
- Never call worker-side helpers (completeOpfs, worker file ops) from application code; treat them as engine internals.
- After HMR issues, do a full reload/rebuild - stale module instances can leave shims registered in the wrong realm.
Defensive patterns
Strategy: validation
Validate before calling
const inWorker =
typeof WorkerGlobalScope !== "undefined" &&
self instanceof WorkerGlobalScope;
if (!inWorker) {
// never call worker-side IO/completion helpers here
} Type guard
const isMainThread = (): boolean => typeof WorkerGlobalScope === "undefined" || !(self instanceof WorkerGlobalScope);
Try / catch
try {
await operation();
} catch (e) {
if (e instanceof Error && /invoked only from the main thread/.test(e.message)) {
// worker imports leaked into the main realm: fix bundler worker config
} else throw e;
} Prevention
- Use official entry points; never import worker-side helpers into app code.
- Disable single-file/inline-worker bundling for the turso worker chunk.
- Full-reload after HMR weirdness to re-register shims in the right realm.
When it happens
Trigger: Bundling both import sets into one context (e.g. a bundler collapsing the worker into the main chunk) so workerImports end up installed on the main thread; manually calling worker-side completion helpers (e.g. completeOpfs) from main-thread code; duplicated module instances where the worker shim registers in the main realm.
Common situations: Aggressive bundler settings (inlineWorker, single-file builds) merging worker and main code; copy-pasted worker bootstrap into a main-thread script; dev-server HMR re-evaluating the wasm-common module in the main realm.
Related errors
- method ${name} must be invoked only from the worker thread
- panic: MainWorker is not initialized
- panic: MainWorker is not initialized
- panic: MainWorker is not initialized
- panic: MainWorker is not initialized
AI-assisted analysis of tursodatabase/turso@244cde92a7 (2026-08-20).
Data as JSON: /api/errors/a47398c7dfb4fe7c.
Report an issue: GitHub.