swc-project/swc · error
{} is not a valid expression
Error message
{} is not a valid expression What it means
Runtime panic while building swc's `jsc.globalPassOptions` (GlobalPassOption::build in crates/swc/src/config/mod.rs). Every entry in `vars` (and every env value, wrapped as `'VALUE'` before parsing) is run through `parse_file_as_expr` with ES syntax; parse errors are emitted to the handler first, then the function panics with `{} is not a valid expression`, printing the offending source text.
Source
Thrown at crates/swc/src/config/mod.rs:2235
fn expr(cm: &SourceMap, handler: &Handler, src: String) -> Box<Expr> {
let fm = cm.new_source_file(FileName::Anon.into(), src);
let mut errors = Vec::new();
let expr = parse_file_as_expr(
&fm,
Syntax::Es(Default::default()),
Default::default(),
None,
&mut errors,
);
for e in errors {
e.into_diagnostic(handler).emit()
}
match expr {
Ok(v) => v,
_ => panic!("{} is not a valid expression", fm.src),
}
}
fn mk_map(
cm: &SourceMap,
handler: &Handler,
values: impl Iterator<Item = (Atom, Atom)>,
is_env: bool,
) -> ValuesMap {
let mut m = HashMap::default();
for (k, v) in values {
let v = if is_env {
format!("'{v}'")
} else {
(*v).into()
};
let v_str = v.clone();View on GitHub (pinned to 5176682b65)
Solutions
- Make each vars value a valid JS expression: quote strings (`'"production"'` or `\"production\"`) and escape embedded quotes
- For envs, sanitize the variable content before it reaches the config — escape or strip single quotes
- Pre-validate every expression string with swc_ecma_parser before handing the config to swc
- Remove `globalPassOptions` if the global inlining pass is not needed
Example fix
// before (.swcrc)
"globalPassOptions": { "vars": { "process.env.MSG": "it's fine" } }
// after (.swcrc)
"globalPassOptions": { "vars": { "process.env.MSG": "\"it's fine\"" } } Defensive patterns
Strategy: validation
Validate before calling
use swc_ecma_parser::{lexer::Lexer, Parser, Syntax, EsSyntax};
use swc_common::{FileName, SourceMap, sync::Lrc};
fn is_valid_js_expr(cm: &Lrc<SourceMap>, src: &str) -> bool {
let fm = cm.new_source_file(FileName::Anon.into(), src.to_string());
let lexer = Lexer::new(
Syntax::Es(EsSyntax::default()),
Default::default(),
&fm,
None,
);
let mut p = Parser::new_from(lexer);
p.parse_expr().is_ok()
}
// validate every globalPassOptions value before building the config
let ok = cfg.global_pass_options
.vars
.iter()
.all(|(k, v)| is_valid_js_expr(&cm, v)); Prevention
- Quote string values in `vars` so they parse as JS string literals
- Escape or strip single quotes from env values before they get wrapped in `'...'`
- Treat environment content as untrusted input to config parsing
When it happens
Trigger: A `.swcrc`/config `jsc.globalPassOptions.vars` value that is not a valid JS expression (e.g. `"1 +"`); or an `envs` entry whose environment variable content contains a single quote (e.g. `IT'S`) — the `'{v}'` wrapping then produces invalid JS and parsing fails.
Common situations: Inline-replacing `process.env.*` with values containing apostrophes or unbalanced quotes/braces; env vars read from user machines (locales, paths) leaking quotes into the generated expression; multiline env values.
Related errors
- .swcrc exists but not matched
- no config matched for file ({name})
- Error occurred while loading config file at ${config}: ${e}
- failed to parse jsx option {}: '{}' is not an expression
- determine_export_name({:?})
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/0bea49dbe8985ec8.
Report an issue: GitHub.