astral-sh/ruff · error · Error

{err}

Error message

{err}

What it means

In ruff's WASM bindings, `into_error` converts any `Display`-able error into the wasm-bindgen `JsError` (`Error::new(&err.to_string())`). Any failure inside the exported WASM API (parse, tokenize, lint of a Python source string) is surfaced to JavaScript as a thrown JS Error whose message is the Rust error's Display text.

Source

Thrown at crates/ruff_wasm/src/lib.rs:520

        Ok(comments)
    }

    /// Parses the content and returns its AST
    pub fn parse(&self, contents: &str) -> Result<String, Error> {
        let parsed = parse_unchecked(contents, ParseOptions::from(Mode::Module));

        Ok(format!("{:#?}", parsed.into_syntax()))
    }

    pub fn tokens(&self, contents: &str) -> Result<String, Error> {
        let parsed = parse_unchecked(contents, ParseOptions::from(Mode::Module));

        Ok(format!("{:#?}", parsed.tokens().as_ref()))
    }
}

pub(crate) fn into_error<E: std::fmt::Display>(err: E) -> Error {
    Error::new(&err.to_string())
}

struct ParsedModule<'a> {
    source_code: &'a str,
    parsed: Parsed<Mod>,
    trivia_ranges: TriviaRanges,
}

impl<'a> ParsedModule<'a> {
    fn from_source(source_code: &'a str) -> Result<Self, Error> {
        let parsed = parse(source_code, ParseOptions::from(Mode::Module)).map_err(into_error)?;
        let trivia_ranges = TriviaRanges::from(parsed.tokens());
        Ok(Self {
            source_code,
            parsed,
            trivia_ranges,
        })
    }

View on GitHub (pinned to 26f38c119c)

Solutions

  1. Inspect the thrown JS Error message — it contains the Rust-side Display text describing the real failure.
  2. Validate/normalize the input source string and parameters before calling the WASM API.
  3. Catch the exception at the JS call site and degrade gracefully (the module itself stays usable).
  4. If the input is valid Python but still fails, report it upstream with a minimal reproducer.

Example fix

// before (JS)
const tokens = wasm.tokenize(source)
// after (JS)
let tokens
try {
  tokens = wasm.tokenize(source)
} catch (e) {
  console.error('ruff wasm failed:', e.message)
  tokens = []
}
Defensive patterns

Strategy: try-catch

Validate before calling

// JS: validate input before calling the WASM API
if (typeof source !== 'string') throw new TypeError('source must be a string')
if (source.length > MAX_SOURCE_LENGTH) throw new RangeError('source too large')

Type guard

function isWasmError(e) {
  return e instanceof Error && typeof e.message === 'string'
}

Try / catch

try {
  result = wasmModule.parse(source)
} catch (e) {
  // e.message contains the Rust Display text from into_error
  console.error('ruff wasm:', e.message)
  result = null
}

Prevention

When it happens

Trigger: Calling a WASM export (e.g. the Playwright/Playground parse or check API) with input that makes the underlying Rust code return `Err`, which is funneled through `into_error` at lib.rs:520 — e.g. invalid Python source causing an unrecoverable parse error path, or a panic converted via catch_unwind.

Common situations: Ruff Playground or the VS Code web extension feeding malformed or unsupported Python code into the WASM module; out-of-memory on huge inputs; passing invalid UTF-16 offsets into position-mapping APIs.

Related errors


AI-assisted analysis of astral-sh/ruff@26f38c119c (2026-09-05). Data as JSON: /api/errors/30822f23711eea11. Report an issue: GitHub.