{"record":{"id":"6f246e0a306edcd4","repo":"swc-project/swc","slug":"swc-does-not-support-pipelineprimarytopicreferenc","errorCode":null,"errorMessage":"swc does not support `PipelinePrimaryTopicReference`","messagePattern":"swc does not support `PipelinePrimaryTopicReference`","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/swc_estree_compat/src/swcify/expr.rs","lineNumber":1122,"sourceCode":"\n    fn swcify(self, _: &Context) -> Self::Output {\n        panic!(\"swc does not support bind expressions\")\n    }\n}\n\nimpl Swcify for DoExpression {\n    type Output = Never;\n\n    fn swcify(self, _: &Context) -> Self::Output {\n        panic!(\"swc does not support do expressions\")\n    }\n}\n\nimpl Swcify for PipelinePrimaryTopicReference {\n    type Output = Never;\n\n    fn swcify(self, _: &Context) -> Self::Output {\n        panic!(\"swc does not support `PipelinePrimaryTopicReference`\")\n    }\n}\n\nimpl Swcify for RecordExpression {\n    type Output = Never;\n\n    fn swcify(self, _: &Context) -> Self::Output {\n        panic!(\"swc does not support record expressions\")\n    }\n}\n\nimpl Swcify for TupleExpression {\n    type Output = Never;\n\n    fn swcify(self, _: &Context) -> Self::Output {\n        panic!(\"swc does not support tuple expressions\")\n    }\n}","sourceCodeStart":1104,"sourceCodeEnd":1140,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_estree_compat/src/swcify/expr.rs#L1104-L1140","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before: acorn/babel parse with pipeline syntax, then convert\nlet swc_expr = estree_expr.swcify(&ctx); // panics: `swc does not support `PipelinePrimaryTopicReference`\n\n// after: lower proposal syntax first (babel), or reject it up front\n// babel.config.js: remove \"pipelineOperator\" from parserOpts.plugin,\n// or precompile: x |> f(#)  ->  f(x)\nlet swc_expr = estree_expr.swcify(&ctx); // ok","handlingStrategy":"type-guard","validationCode":"// Walk the ESTree JSON before swcify; reject unsupported proposal nodes.\nfn find_unsupported(v: &serde_json::Value, out: &mut Vec<String>) {\n    if let Some(t) = v.get(\"type\").and_then(|t| t.as_str()) {\n        if is_unsupported_estree_type(t) { out.push(t.to_string()); }\n    }\n    if let Some(map) = v.as_object() {\n        for child in map.values() { find_unsupported(child, out); }\n    }\n    if let Some(arr) = v.as_array() {\n        for child in arr { find_unsupported(child, out); }\n    }\n}\nlet mut bad = Vec::new();\nfind_unsupported(&estree_json, &mut bad);\nif !bad.is_empty() { return Err(format!(\"unsupported ESTree nodes: {bad:?}\")); }","typeGuard":"fn is_unsupported_estree_type(t: &str) -> bool {\n    matches!(\n        t,\n        \"PipelinePrimaryTopicReference\" | \"BindExpression\" | \"DoExpression\"\n            | \"RecordExpression\" | \"TupleExpression\" | \"ModuleExpression\"\n    )\n}","tryCatchPattern":"let out = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {\n    estree_expr.swcify(&ctx)\n}));\nmatch out {\n    Ok(node) => node,\n    Err(payload) => return Err(format!(\n        \"swcify rejected an unsupported ESTree node: {payload:?}\"\n    )),\n}","preventionTips":["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"],"tags":["estree-compat","swcify","ast-conversion","pipeline-operator","panic"],"backgroundTag":"unsupported-syntax-feature","analyzedSha":"5176682b65416c6b5de6b47379ae1588ea3ecb3f","analyzedAt":"2026-08-17T16:16:52.067Z","contentChangedAt":"2026-08-17T16:16:52.067Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}