parcel-bundler/parcel · error · napi::Error

GenericFailure

GenericFailure

Error message

resolveAsync does not support custom fs or module_dir_resolver

What it means

Thrown by resolve_async when the Resolver was constructed with a custom fs or a module_dir_resolver. The async path uses rayon::spawn and only supports the OS filesystem (supports_async is set true only when no custom fs is supplied). The check is an explicit guard before spawning, so the error fires synchronously on the call, not inside the promise.

Source

Thrown at crates/node-bindings/src/resolver.rs:283

      resolve_internal(&self.resolver, self.mode, options)?;
    resolve_result_to_js(env, res, invalidations, side_effects, module_type)
  }

  #[cfg(target_arch = "wasm32")]
  #[napi]
  pub fn resolve_async(&'static self) -> Result<JsObject> {
    panic!("resolveAsync() is not supported in Wasm builds")
  }

  #[cfg(not(target_arch = "wasm32"))]
  #[napi]
  pub fn resolve_async(&'static self, options: ResolveOptions, env: Env) -> Result<JsObject> {
    let (deferred, promise) = env.create_deferred()?;
    let resolver = &self.resolver;
    let mode = self.mode;

    if !self.supports_async || resolver.module_dir_resolver.is_some() {
      return Err(napi::Error::new(
        napi::Status::GenericFailure,
        "resolveAsync does not support custom fs or module_dir_resolver",
      ));
    }

    rayon::spawn(move || {
      let (res, invalidations, side_effects, module_type) =
        match resolve_internal(&resolver, mode, options) {
          Ok(r) => r,
          Err(e) => return deferred.reject(e),
        };

      deferred.resolve(move |env| {
        resolve_result_to_js(env, res, invalidations, side_effects, module_type)
      });
    });

    Ok(promise)

View on GitHub (pinned to 59484858a1)

Solutions

  1. Use the synchronous resolve() method instead of resolveAsync() when a custom fs or module_dir_resolver is required.
  2. Drop the custom fs option (use the default OS filesystem) if you need async and can tolerate real-disk resolution.
  3. Drop the moduleDirResolver option and handle module directory resolution in a wrapper around sync resolve.
  4. If you need both custom fs and non-blocking behavior, run sync resolve() in a worker thread yourself.

Example fix

// before
const resolver = new Resolver(root, { fs: customFs, mode: 1 });
const result = await resolver.resolveAsync(opts); // throws GenericFailure

// after — use sync resolve, offload if you need non-blocking
const resolver = new Resolver(root, { fs: customFs, mode: 1 });
const result = resolver.resolve(opts); // synchronous, works with custom fs
Defensive patterns

Strategy: validation

Validate before calling

// Before calling resolveAsync, confirm the Resolver was built without custom fs / module_dir_resolver
function canResolveAsync(resolverOptions) {
  return resolverOptions.fs == null && resolverOptions.moduleDirResolver == null;
}
if (!canResolveAsync(originalOptions)) {
  // use sync resolve instead
  return resolver.resolve(opts);
}
return await resolver.resolveAsync(opts);

Type guard

function resolverSupportsAsync(opts) {
  return opts.fs === undefined && opts.moduleDirResolver === undefined;
}

Try / catch

try {
  return await resolver.resolveAsync(opts);
} catch (e) {
  if (e.message.includes('does not support custom fs')) {
    // fall back to synchronous resolution
    return resolver.resolve(opts);
  }
  throw e;
}

Prevention

When it happens

Trigger: Constructing a Resolver with options.fs (a custom JsFileSystemOptions) or options.moduleDirResolver (a function), then calling resolver.resolveAsync(opts). Either condition independently triggers the error. Using OsFileSystem (no fs option) with no module_dir_resolver allows async.

Common situations: Building a resolver over a virtual/remote filesystem and wanting non-blocking resolution; integrating a custom module directory resolver for monorepo setups and assuming it composes with async; copying a sync-configured Resolver into an async code path.

Related errors


AI-assisted analysis of parcel-bundler/parcel@59484858a1 (2026-08-13). Data as JSON: /api/errors/a7bcdfb8c54dfabd. Report an issue: GitHub.