swc-project/swc · error · anyhow::Error

Invalid path "{path:?}"

Error message

Invalid path "{path:?}"

What it means

Thrown by preset_env_base's targets_to_versions (crates/preset_env_base/src/query.rs) when a provided `path` cannot be converted to a UTF-8 String before being handed to browserslist as the config search directory (OsString::into_string fails on invalid UTF-8 bytes). It only occurs on non-wasm targets when env.targets is None, i.e. when browserslist config discovery is being performed relative to that path.

Source

Thrown at crates/preset_env_base/src/query.rs:132

        Ok(result)
    }
}

pub fn targets_to_versions(v: Option<Targets>, path: Option<PathBuf>) -> Result<TargetInfo, Error> {
    match v {
        #[cfg(not(target_arch = "wasm32"))]
        None => {
            let mut browserslist_opts = browserslist::Opts {
                mobile_to_desktop: true,
                ignore_unknown_versions: true,
                ..Default::default()
            };
            if let Some(path) = path {
                browserslist_opts.path = path
                    .clone()
                    .into_os_string()
                    .into_string()
                    .map_err(|_| anyhow!("Invalid path \"{path:?}\""))?
                    .into();
            }
            let distribs = browserslist::execute(&browserslist_opts)
                .with_context(|| "failed to resolve browserslist query from browserslist config")?;

            // When targets is None, it means the user didn't specify any targets.
            // We use browserslist config or defaults, so we should NOT treat empty
            // results as "unknown version". That case is for when a user explicitly
            // specifies a query like "Chrome > 99999" that returns empty.
            let versions = BrowserData::parse_versions(distribs)
                .with_context(|| "failed to parse browser version")?;

            Ok(TargetInfo {
                versions: Arc::new(versions),
                unknown_version: false,
            })
        }
        #[cfg(target_arch = "wasm32")]

View on GitHub (pinned to d7d7434666)

Solutions

  1. Rename the offending directory (or run the build from) a path containing only valid UTF-8 characters
  2. Specify explicit env.targets (or a browserslist query) in swc options so the filesystem config lookup with `path` is skipped
  3. On Windows, ensure the path is not encoded in a legacy code page (check with a UTF-8 aware shell); on Unix, run `iconv`-style validation of the path bytes
  4. Report upstream: browserslist's Opts.path could accept an OsString/PathBuf representation to avoid the lossy conversion

Example fix

# before: project lives at a non-UTF-8 path
~/Jos\xe9/project $ npx swc src -d out   # -> Invalid path

# after: move or symlink to a UTF-8 path
~/projects/jose/project $ npx swc src -d out
Defensive patterns

Strategy: validation

Validate before calling

// Rust callers of preset_env_base: validate before invoking targets_to_versions
fn ensure_utf8_path(path: &Path) -> Result<&str> {
    path.to_str().ok_or_else(|| {
        anyhow::anyhow!(
            "config path {} is not valid UTF-8; rename it or pass explicit targets",
            path.display()
        )
    })
}
// JS/CLI side: run the build from a UTF-8-only path
// const ok = /^[\x00-\x7f -￿]*$/.test(process.cwd());

Try / catch

// JS callers of @swc/core compile APIs
try {
  await compileSwc(src, { /* no env.targets -> browserslist config lookup */ });
} catch (e) {
  if (String(e).includes('Invalid path')) {
    // path bytes are not UTF-8: move the project or set explicit targets
    return compileSwc(src, { env: { targets: 'defaults' } });
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling swc compile/preset-env without explicit targets while the project/config directory path contains non-UTF-8 bytes - e.g. Latin-1/CP1252 accented characters in a directory name on Windows or macOS, or invalid UTF-8 sequences from a misconfigured filesystem; the path is then used for browserslist's config lookup.

Common situations: Machines with localized usernames ('José', 'Dvořák') producing non-UTF-8 encodings; CI checkouts into byte-encoded paths; archives that preserved legacy encodings; monorepos whose root path includes such segments.

Related errors


AI-assisted analysis of swc-project/swc@d7d7434666 (2026-08-16). Data as JSON: /api/errors/545827aa6ef840e3. Report an issue: GitHub.