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

failed parse json as javascript object: {err:#?}

Error message

failed parse json as javascript object: {err:#?}

What it means

Thrown by swc_node_bundler's JSON loader: a .json module is parsed with parse_file_as_expr (Es2020 expression parser) to convert it into module.exports = {...}, and that parse failed. JSON is almost always a valid JS expression, so failure means the file contains content that is not strict JSON-as-expression.

Source

Thrown at crates/swc_node_bundler/src/loaders/json.rs:17

use std::sync::Arc;

use anyhow::{anyhow, Error};
use swc_atoms::atom;
use swc_common::{SourceFile, DUMMY_SP};
use swc_ecma_ast::*;
use swc_ecma_parser::{parse_file_as_expr, Syntax};

pub(super) fn load_json_as_module(fm: &Arc<SourceFile>) -> Result<Module, Error> {
    let expr = parse_file_as_expr(
        fm,
        Syntax::default(),
        EsVersion::Es2020,
        None,
        &mut Vec::new(),
    )
    .map_err(|err| anyhow!("failed parse json as javascript object: {err:#?}"))?;

    let export = ExprStmt {
        span: DUMMY_SP,
        expr: AssignExpr {
            span: DUMMY_SP,
            op: op!("="),
            left: MemberExpr {
                span: DUMMY_SP,
                obj: Box::new(Ident::new_no_ctxt(atom!("module"), DUMMY_SP).into()),
                prop: MemberProp::Ident(IdentName::new(atom!("exports"), DUMMY_SP)),
            }
            .into(),
            right: expr,
        }
        .into(),
    }
    .into();

View on GitHub (pinned to d7d7434666)

Solutions

  1. Validate the file with a strict JSON parser (JSON.parse) and fix whatever it flags: remove comments, trailing commas, NaN/Infinity, quote keys
  2. Rename true JSONC files to .jsonc/.json5 and keep them out of the bundler's json loader path, or pre-transpile them
  3. Strip BOM before the file reaches the loader

Example fix

// data.json before (comment - invalid as JS expression source for strict JSON)
// build config
{ "a": 1, }

// after
{ "a": 1 }
Defensive patterns

Strategy: validation

Validate before calling

// Rust: strict-parse JSON before it reaches the bundler
fn json_is_strict(path: &Path) -> Result<(), String> {
    let raw = std::fs::read_to_string(path).map_err(|e| e.to_string())?;
    let trimmed = raw.trim_start_matches('\u{feff}'); // strip BOM
    serde_json::from_str::<serde_json::Value>(trimmed)
        .map(|_| ())
        .map_err(|e| format!("{} is not strict JSON: {e}", path.display()))
}

Try / catch

match load_json_as_module(&fm) {
    Err(e) if e.to_string().contains("failed parse json as javascript object") => {
        anyhow::bail!("file {} must be strict JSON (no comments/trailing commas/NaN)", fm.name)
    }
    other => other,
}

Prevention

When it happens

Trigger: Bundling with the node bundler where a .json import contains top-level comments, trailing commas, NaN/Infinity/undefined literals, unquoted or duplicate-ish syntax, a BOM, or is actually JSONC/JSON5 - all rejected by the Es2020 parser.

Common situations: Projects mixing tsconfig-style commented JSON into files that get imported (e.g. importing a config written as JSONC), editor tooling saving with BOM, or generated files containing Infinity from serialization.

Related errors


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