{"record":{"id":"34c93846b6fb1698","repo":"swc-project/swc","slug":"non-computed-member-expression-with-property-other","errorCode":null,"errorMessage":"Non-computed member expression with property other than ident is invalid","messagePattern":"Non-computed member expression with property other than ident is invalid","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/swc_bundler/src/bundler/import/mod.rs","lineNumber":318,"sourceCode":"                });\n                let import = match import {\n                    Some(v) => v,\n                    None => return,\n                };\n\n                let src_atom = import.src.value.to_atom_lossy();\n                let mark = self.ctxt_for(src_atom.as_ref());\n                let exported_ctxt = match mark {\n                    None => return,\n                    Some(ctxts) => ctxts.1,\n                };\n                let prop = match &e.prop {\n                    MemberProp::Ident(i) => {\n                        let mut i = Ident::from(i.clone());\n                        i.ctxt = exported_ctxt;\n                        i\n                    }\n                    _ => unreachable!(\n                        \"Non-computed member expression with property other than ident is invalid\"\n                    ),\n                };\n\n                self.usages\n                    .entry(obj.to_id())\n                    .or_default()\n                    .push(prop.to_id());\n            }\n        }\n    }\n\n    fn try_deglob(&mut self, e: &mut Expr) {\n        let me = match e {\n            Expr::Member(e) => e,\n            _ => return,\n        };\n        if me.prop.is_computed() {","sourceCodeStart":300,"sourceCodeEnd":336,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_bundler/src/bundler/import/mod.rs#L300-L336","documentation":"During bundler import analysis, member expressions on imported bindings (`ns.prop`) are recorded as usages with the exported context applied to the property identifier. A non-computed member must have MemberProp::Ident; this arm fires when the property is a PrivateName (`ns.#field`) — private-name access on an import namespace binding, which the bundler cannot rewrite and which is invalid in that position in ECMAScript.","triggerScenarios":"Source like `import * as foo from './foo'; foo.#bar` (invalid JS but producible by hand-built or machine-generated AST) fed to swc_bundler; transforms/macros that clone private-name member expressions onto imported bindings.","commonSituations":"Code generation tools or macro output that emit `.#prop` outside class bodies; hand-constructed swc_ecma_ast trees that skip validation; sloppy-mode scripts with unusual syntax accepted by lenient parsers.","solutions":["Fix the input source: private fields can only be accessed inside the class that declares them; use a normal property","If you build AST programmatically, validate MemberExpr nodes (reject MemberProp::PrivateName on imported bindings) before handing modules to the bundler","If valid parsed input reaches this, report it to swc with the exact snippet"],"exampleFix":"// before\nimport * as foo from './foo';\nconsole.log(foo.#secret);\n\n// after\nimport * as foo from './foo';\nconsole.log(foo.secret);","handlingStrategy":"validation","validationCode":"// Reject private-name member access on imported namespaces before bundling\nlet private_member = regex::Regex::new(r\"\\.#[A-Za-z_$]\").unwrap();\nfor (path, src) in &sources {\n    if private_member.is_match(src) {\n        return Err(format!(\"{}: `.#field` outside a class body is invalid\", path));\n    }\n}","typeGuard":"// If building AST programmatically, walk it first\nfn has_invalid_private_member(m: &swc_ecma_ast::Module) -> bool {\n    struct V(bool);\n    impl Visit for V {\n        fn visit_member_expr(&mut self, e: &MemberExpr) {\n            if matches!(e.prop, MemberProp::PrivateName(_)) { self.0 = true; }\n            e.visit_children_with(self);\n        }\n    }\n    let mut v = V(false);\n    m.visit_with(&mut v);\n    v.0\n}","tryCatchPattern":"if let Err(p) = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| bundler.bundle(&entries))) {\n    if panic_message(&p).contains(\"Non-computed member expression\") {\n        // surface a user-facing error about invalid `.#prop` usage instead of crashing\n    } else { std::panic::resume_unwind(p); }\n}","preventionTips":["Never generate `.#prop` member expressions outside class bodies","Validate hand-built AST with a visitor before passing it to the bundler","Lint sources for `.#` sequences in bundler inputs"],"tags":["swc","bundler","private-field","member-expression","ast"],"backgroundTag":"invalid-private-field-access","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"}