swc-project/swc · error

Failed to parse the input

Error message

Failed to parse the input

What it means

Thrown by the wasm-bindgen `parse` entry point of the AST viewer binding (bindings/binding_es_ast_viewer). The SWC parser (parse_module / parse_commonjs / parse_program, chosen from the file_name extension) returned an Err, so no Program could be built. The real parser diagnostic is first emitted into the swc error handler, and this anyhow message is the wrapper that reaches JS as a pretty-printed string. Syntax (TS vs ES, JSX, d.ts, module/goal) is inferred purely from the extension of `file_name` (default "main.mtsx"), so a mismatch between content and extension also lands here.

Source

Thrown at bindings/binding_es_ast_viewer/src/lib.rs:97

        parser.parse_commonjs().map(Program::Script)
    } else {
        parser.parse_program()
    };

    let mut ast = try_with_handler(
        cm,
        HandlerOpts {
            color: ColorConfig::Never,
            ..Default::default()
        },
        |handler| {
            for err in parser.take_errors() {
                err.into_diagnostic(handler).emit();
            }

            program.map_err(|err| {
                err.into_diagnostic(handler).emit();
                anyhow::anyhow!("Failed to parse the input")
            })
        },
    )
    .map_err(|err| err.to_pretty_string())?;

    let tokens = parser.input_mut().iter_mut().take();

    GLOBALS.set(&Globals::default(), || {
        let unresolved_mark = Mark::new();
        let top_level_mark = Mark::new();
        ast.visit_mut_with(&mut resolver(unresolved_mark, top_level_mark, is_ts));

        Ok(vec![format!("{ast:#?}"), format!("{tokens:#?}")])
    })
}

#[wasm_bindgen]
pub fn version() -> String {

View on GitHub (pinned to d7d7434666)

Solutions

  1. Read the emitted diagnostic inside the returned error string - it contains file, line, and column of the real syntax error - and fix that location in the input
  2. Pass a second file_name argument whose extension matches the content, e.g. parse(code, 'input.tsx') for TSX or parse(code, 'input.js') for plain ES
  3. If the content is TypeScript, never name it .js/.mjs/.cjs; if it is JSX-free TS, a .ts name avoids JSX-only parsing quirks
  4. Verify the snippet elsewhere first (e.g. tsc --noEmit or swc CLI) before feeding it to the viewer
  5. Upgrade @swc/wasm-ast-viewer if the input is valid but the parser version is stale

Example fix

// before: TSX content, default file name 'main.mtsx' actually works for tsx,
// but plain JS with class properties fails under the TS grammar
const out = parse('class A { #x = 1; }');

// after: name it as JavaScript so Syntax::Es (jsx off) is selected
const out = parse('class A { #x = 1; }', 'input.mjs');
Defensive patterns

Strategy: try-catch

Try / catch

// wasm-bindgen Result<_, String> surfaces as a thrown string in JS
try {
  const [ast, tokens] = parse(code, fileName);
} catch (e) {
  // e is a pretty-printed string containing the real parser diagnostic
  console.error(String(e));
  throw new Error('AST viewer could not parse input: ' + e);
}

Prevention

When it happens

Trigger: Calling parse() on syntactically invalid JS/TS; passing TSX or JSX content while file_name's extension is not one of jsx/tsx/mjsx/cjsx/mtsx/ctsx (so jsx: false disables JSX parsing); passing TypeScript-only syntax with a .js/.mjs/.cjs file_name (Syntax::Es is selected); passing a .cjs file where parse_commonjs is used on ESM content, or a .mjs file on CJS content.

Common situations: Using the default file name (main.mtsx) for plain-JS-with-decorators or proposals the TS parser rejects; typo'd extensions like 'tss' or 'jsx.'; exploring draft/partial files or non-source text pasted into an AST viewer UI; older @swc/wasm-ast-viewer packages with a stricter TS parser.

Understand the failure class

Related errors


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