Skip to content

Troubleshooting

Opening rejects with a worker or isolation error

In a browser, a request for threads > 1 requires globalThis.crossOriginIsolated === true and SharedArrayBuffer. Use HTTPS or localhost, verify the COOP and COEP headers, and check the browser console. For a local threaded baseline, run npm start in js/.

For browser execution without isolation, use threads: 1 or omit threads. The serial build needs neither isolation headers nor SharedArrayBuffer. An explicit request for multiple browser threads rejects on a non-isolated page. Try npm start -- --no-isolation locally. See frontend hosting.

Node.js 22 and later uses node:worker_threads; it does not need browser isolation headers. Node defaults to threads: 1, and explicit counts above one use the threaded build when within host capacity.

JavaScript options.threads is separate from the INP THREADS setting. Serial WASM accepts inputs such as THREADS 4 and clamps the solver count to one. If threaded initialization rejects an INP request above capacity, reduce the INP THREADS setting or increase JavaScript options.threads within the runtime's supported maximum.

Worker, WASM, or snippet requests fail

Inspect the network panel for missing assets, MIME errors, blocked cross-origin resources, or responses containing HTML instead of JavaScript/WASM. Deploy lib/swmmrs/ and dist/, including dist/snippets/ and dist/serial/, from the same build. Keep their relative paths intact and set workerUrl if your server places the worker at a different public URL.

The solver reports an invalid input file

Pass INP contents, not a path or URL string. In Node, read the file with node:fs/promises and pass the returned bytes. In a browser, check the fetch response status before using its body. For supporting files, match each relative INP reference to a supplied key, including directory components. Read the error's report when available; some early parsing errors only return a generic message.

An operation throws LifecycleError

Check await simulation.getState(). Configure before starting or after finalization. Read object results and quality after starting. Read system and per-object statistics before finish(). Do not manually advance or finalize inside an active iterator. terminate() is valid only while that iterator is active. Closed owners, collections, and handles cannot be reused. See the state table.

Values do not change in the UI

A results(), quality(), or configuration() record is a detached copy. Call the method again after advancing, or collect a fresh snapshot. Assignments to records do not edit the solver. Use configure() or a runtime control method. Related objects in configuration records are represented by IDs, not foreign handles.

Check project units as well: subcatchment fractions are 0 to 1, slopes are ratios, and model timestamps are calendar strings without a timezone. See units and time.

Progress or stopping does not respond during a run

run() and runSwmm() occupy the simulation worker for the entire native batch request. They have no progress callback, AbortSignal, or hard interrupt. Use steps() for periodic UI updates and call terminate() for cooperative stopping at the next observation boundary. close() is cleanup and does not interrupt an in-flight native operation.

Rainfall does not return after clearing an override

setRainfallOverride(null) clears the override only. If you previously called setPrecipitation(), the API source remains selected, even when its rate is zero. Open a fresh model to restore its original source and co-gage setup. See Runtime forcings.

Binary output cannot be queried

OutputReader.open() needs output bytes. With saveResults: false, RunResults.output is intentionally empty. Use live snapshots instead, or run with saveResults: true and query the bytes through OutputReader. A reader can inspect valid incomplete output, but it still owns a worker and must be closed.

Types are missing or cannot be imported as values

Build the package before consuming it, and import from the public root "@swmmrs/swmmrs". Obtain Node, Link, Subcatchment, RainGage, and specialized handles from their collections; they have no public constructors. Import record interfaces and string unions with import type. Simulation, runSwmm, OutputReader, and exception classes are runtime exports.

Validate a local build

From js/, run npm run typecheck for the public TypeScript contract, npm test for browser integration tests, and npm run test:package to inspect packaged assets. Browser tests require Playwright Chromium or CHROMIUM_PATH pointing to an installed Chromium binary.

npm run test:docs type-checks documentation TypeScript examples against the built public declarations. It does not replace browser integration tests.