swc-project/swc · error
failed to parse the value of DecimalLiteral
Error message
failed to parse the value of DecimalLiteral
What it means
Thrown while converting an ESTree DecimalLiteral into swc's Number node (swc_estree_compat `swcify`). The `value` string is parsed with Rust's `f64::from_str`, which accepts only standard float syntax (digits, optional '.', exponent, optional sign, inf/NaN); the `.expect(...)` panics on any other content. ESTree decimal-proposal literals keep the 'm' suffix in their textual value (e.g. "1.1m"), which f64 parsing rejects, as do 'n' BigInt suffixes, whitespace, and empty strings.
Source
Thrown at crates/swc_estree_compat/src/swcify/lit.rs:161
.parse()
.map(Box::new)
.expect("failed to parse the value of BigIntLiteral"),
// TODO improve me
raw: None,
}
}
}
impl Swcify for DecimalLiteral {
type Output = Number;
fn swcify(self, ctx: &Context) -> Self::Output {
Number {
span: ctx.span(&self.base),
value: self
.value
.parse()
.expect("failed to parse the value of DecimalLiteral"),
// TODO improve me
raw: None,
}
}
}
View on GitHub (pinned to 5176682b65)
Solutions
- Normalize the value before converting: strip a trailing 'm' (and any 'n' or separators) so the string is a plain decimal number
- If you generate the ESTree AST yourself, emit value as a plain numeric string like "1.1"
- Filter/validate DecimalLiteral nodes before running swcify and surface a proper error instead of a panic
- Patch the crate to use a fallible parse and report the value in a diagnostic
Example fix
// before
// node = { type: 'DecimalLiteral', value: '1.1m' }
swcify(node); // panics: failed to parse the value of DecimalLiteral
// after
node.value = node.value.replace(/[mn]$/, ''); // '1.1'
swcify(node); Defensive patterns
Strategy: validation
Validate before calling
function decimalValueOk(node) {
if (node.type !== 'DecimalLiteral') return true;
const v = String(node.value).replace(/[mn]$/, '');
return v !== '' && !Number.isNaN(Number(v));
}
const bad = nodes.filter(n => !decimalValueOk(n));
if (bad.length) throw new Error(`unparseable DecimalLiteral value: ${bad[0].value}`); Type guard
function isParseableDecimalLiteral(node: unknown): boolean {
if (typeof node !== 'object' || node === null) return false;
const n = node as { type?: string; value?: unknown };
if (n.type !== 'DecimalLiteral') return false;
if (typeof n.value !== 'string') return false;
const v = n.value.replace(/[mn]$/, '');
return v !== '' && !Number.isNaN(Number(v));
} Try / catch
// Rust: convert the panic into an error at the boundary
let out = std::panic::catch_unwind(|| ast.swcify(&ctx))
.map_err(|_| anyhow::anyhow!("DecimalLiteral value failed to parse; check for 'm' suffix")); Prevention
- Strip the decimal 'm' (and bigint 'n') suffixes from literal values at ingestion, before any AST conversion
- Reject empty string values when reading ASTs from JSON sources
- Add fixture tests covering decimal/bigint literals to your conversion pipeline
When it happens
Trigger: Calling `.swcify(ctx)` on a tree containing a DecimalLiteral whose `value` is not parseable as f64: value="1.1m", value="0.3m", value="10n", value="", or value with whitespace/thousand separators.
Common situations: Converting ASTs from parsers that support the (withdrawn) JS decimal proposal and leave the 'm' suffix in value; mixing BigInt values into decimal nodes; hand-crafted fixtures; lossy JSON round-trips that empty the value field.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to parse the value of BigIntLiteral
- swc does not support `PipelinePrimaryTopicReference`
- swc does not support record expressions
- swc does not support tuple expressions
- swc does not support module expressions
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/d0c51ab8504622bc.
Report an issue: GitHub.