swc-project/swc · error
swc does not support `PipelinePrimaryTopicReference`
Error message
swc does not support `PipelinePrimaryTopicReference`
What it means
swc_estree_compat converts an ESTree-shaped AST (swc_estree_ast) into SWC's AST via the Swcify trait. PipelinePrimaryTopicReference is the `#` placeholder of the pipeline-operator proposal; swc_ecma_ast has no node for it, so the impl declares `type Output = Never` and panics as a hard stop when swcify reaches such a node. The conversion cannot produce any valid SWC node for this syntax.
Source
Thrown at crates/swc_estree_compat/src/swcify/expr.rs:1122
fn swcify(self, _: &Context) -> Self::Output {
panic!("swc does not support bind expressions")
}
}
impl Swcify for DoExpression {
type Output = Never;
fn swcify(self, _: &Context) -> Self::Output {
panic!("swc does not support do expressions")
}
}
impl Swcify for PipelinePrimaryTopicReference {
type Output = Never;
fn swcify(self, _: &Context) -> Self::Output {
panic!("swc does not support `PipelinePrimaryTopicReference`")
}
}
impl Swcify for RecordExpression {
type Output = Never;
fn swcify(self, _: &Context) -> Self::Output {
panic!("swc does not support record expressions")
}
}
impl Swcify for TupleExpression {
type Output = Never;
fn swcify(self, _: &Context) -> Self::Output {
panic!("swc does not support tuple expressions")
}
}View on GitHub (pinned to 5176682b65)
Solutions
- Disable the pipeline-operator syntax plugin in the upstream ESTree parser so `#` topic references never reach swcify
- Pre-compile the code with @babel/plugin-proposal-pipeline-operator (or equivalent) down to plain calls before converting
- Parse the source with swc_ecma_parser directly instead of converting a foreign ESTree AST
- If you build the ESTree AST yourself, rewrite PipelinePrimaryTopicReference nodes into a plain identifier bound before the pipeline before calling swcify
Example fix
// before: acorn/babel parse with pipeline syntax, then convert let swc_expr = estree_expr.swcify(&ctx); // panics: `swc does not support `PipelinePrimaryTopicReference` // after: lower proposal syntax first (babel), or reject it up front // babel.config.js: remove "pipelineOperator" from parserOpts.plugin, // or precompile: x |> f(#) -> f(x) let swc_expr = estree_expr.swcify(&ctx); // ok
Defensive patterns
Strategy: type-guard
Validate before calling
// Walk the ESTree JSON before swcify; reject unsupported proposal nodes.
fn find_unsupported(v: &serde_json::Value, out: &mut Vec<String>) {
if let Some(t) = v.get("type").and_then(|t| t.as_str()) {
if is_unsupported_estree_type(t) { out.push(t.to_string()); }
}
if let Some(map) = v.as_object() {
for child in map.values() { find_unsupported(child, out); }
}
if let Some(arr) = v.as_array() {
for child in arr { find_unsupported(child, out); }
}
}
let mut bad = Vec::new();
find_unsupported(&estree_json, &mut bad);
if !bad.is_empty() { return Err(format!("unsupported ESTree nodes: {bad:?}")); } Type guard
fn is_unsupported_estree_type(t: &str) -> bool {
matches!(
t,
"PipelinePrimaryTopicReference" | "BindExpression" | "DoExpression"
| "RecordExpression" | "TupleExpression" | "ModuleExpression"
)
} Try / catch
let out = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
estree_expr.swcify(&ctx)
}));
match out {
Ok(node) => node,
Err(payload) => return Err(format!(
"swcify rejected an unsupported ESTree node: {payload:?}"
)),
} Prevention
- Keep proposal syntax (pipeline operator) disabled in any parser whose output feeds swc_estree_compat
- Lower stage-1/2 syntax with babel transforms to standard JS before ESTree-to-SWC conversion
- Prefer parsing source with swc_ecma_parser so unsupported syntax fails at parse time with a diagnostic
- Add fixture tests containing `#` topic references to catch regressions early
When it happens
Trigger: Calling `.swcify(ctx)` on an ESTree expression tree that contains a PipelinePrimaryTopicReference node, produced by parsing code like `x |> f(#)` or `# |> f` with the pipeline-operator syntax enabled in the upstream ESTree parser (e.g. @babel/plugin-syntax-pipeline-operator or an acorn plugin).
Common situations: Feeding babel/acorn output into SWC through swc_estree_compat while the source still contains stage-1 pipeline syntax; astexplorer-style tools that round-trip ESTree ASTs; forgetting to lower proposal syntax with babel before conversion.
Related errors
- swc does not support record expressions
- swc does not support tuple expressions
- swc does not support module expressions
- failed to parse the value of BigIntLiteral
- failed to parse the value of DecimalLiteral
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/6f246e0a306edcd4.
Report an issue: GitHub.