{"record":{"id":"c8322c5ea3078b23","repo":"denoland/deno","slug":"err-wasi-not-started","errorCode":"ERR_WASI_NOT_STARTED","errorMessage":"wasi.start() has not been called","messagePattern":"wasi\\.start\\(\\) has not been called","errorType":"exception","errorClass":"ERR_WASI_NOT_STARTED","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/wasi.ts","lineNumber":669,"sourceCode":"          siFlags,\n          soDatalenPtr,\n          self.#getMemoryBuffer(),\n        );\n      },\n      sock_shutdown(fd: number, how: number) {\n        return ctx.sockShutdown(fd, how);\n      },\n      sock_accept(fd: number, flags: number, fdPtr: number) {\n        return ctx.sockAccept(fd, flags, fdPtr, self.#getMemoryBuffer());\n      },\n    };\n  }\n\n  #memory: WebAssembly.Memory | null = null;\n\n  #getMemoryBuffer(): Uint8Array {\n    if (!this.#memory) {\n      throw new ERR_WASI_NOT_STARTED();\n    }\n    // deno-lint-ignore deno-internal/prefer-primordials -- WebAssembly.Memory.prototype.buffer getter; no primordial equivalent\n    return new Uint8Array(this.#memory.buffer);\n  }\n\n  get wasiImport() {\n    return this.#wasiImport;\n  }\n\n  getImportObject() {\n    if (this.#version === \"unstable\") {\n      return { wasi_unstable: this.#wasiImport };\n    }\n    return { wasi_snapshot_preview1: this.#wasiImport };\n  }\n\n  start(instance?: WebAssembly.Instance): number {\n    if (this.#started) {","sourceCodeStart":651,"sourceCodeEnd":687,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/wasi.ts#L651-L687","documentation":"ERR_WASI_NOT_STARTED is thrown when a WASI import function needs the module's linear memory but none has been bound yet. Memory is captured in #getMemoryBuffer() from this.#memory, which is only set by start(), initialize(), or finalizeBindings(). If the wasm module calls any WASI function that touches memory (path_read, fd_write, args_get, ...) before one of those ran, this error surfaces.","triggerScenarios":"Instantiating the module with `new WebAssembly.Instance(module, { wasi_snapshot_preview1: wasi.wasiImport })` and then calling `instance.exports._start()` directly instead of `wasi.start(instance)`; calling `wasi.getImportObject()` and letting the module run during instantiation (e.g. a start section that traps) before start() binds memory; invoking import functions manually from JS for testing.","commonSituations":"Wrapping instantiation in a helper that hides the wasi object so the caller forgets the start() step; porting code from a runtime where imports auto-attach memory; splitting instantiate/start across modules where ordering is not enforced.","solutions":["Call `wasi.start(instance)` (command modules) or `wasi.initialize(instance)` (reactor modules) before invoking any exports or letting the module call WASI imports.","Never call `instance.exports._start()` yourself; start() does that after binding memory.","Keep instantiation and start in the same function so the ordering cannot be broken by refactoring."],"exampleFix":"// before\nconst instance = new WebAssembly.Instance(module, { wasi_snapshot_preview1: wasi.wasiImport });\ninstance.exports._start(); // ERR_WASI_NOT_STARTED inside the first WASI call\n\n// after\nconst instance = new WebAssembly.Instance(module, { wasi_snapshot_preview1: wasi.wasiImport });\nwasi.start(instance); // binds memory, then invokes _start","handlingStrategy":"validation","validationCode":"// Enforce ordering: instantiate and start in one step.\nfunction instantiateAndStart(\n  wasi: WASI,\n  module: WebAssembly.Module,\n): WebAssembly.Instance {\n  const instance = new WebAssembly.Instance(module, wasi.getImportObject());\n  wasi.start(instance); // binds memory before _start runs\n  return instance;\n}","typeGuard":null,"tryCatchPattern":"try {\n  wasi.start(instance);\n} catch (err) {\n  if ((err as { code?: string }).code === 'ERR_WASI_NOT_STARTED') {\n    // memory never bound: lifecycle out of order\n    throw new Error('Call wasi.start(instance) before invoking exports');\n  }\n  throw err;\n}","preventionTips":["Never call instance.exports._start() directly; always route through wasi.start().","Keep new WebAssembly.Instance(...) and wasi.start(...) adjacent in the same function.","Wrap the instantiate+start pair in one helper so ordering cannot drift."],"tags":["wasi","webassembly","lifecycle","memory","node-compat"],"backgroundTag":"call-before-initialize","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}