{"record":{"id":"7d56cad8b02eac5d","repo":"swc-project/swc","slug":"emitting-decorator-metadata-while-using-new-propos","errorCode":null,"errorMessage":"emitting decorator metadata while using new proposal","messagePattern":"emitting decorator metadata while using new proposal","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/swc_ecma_transforms_proposal/src/decorators/mod.rs","lineNumber":65,"sourceCode":"/// ```js\n/// class C {\n///   @enumerable(false)\n///   method() { }\n/// }\n///\n/// function enumerable(value) {\n///   return function (target, key, descriptor) {\n///      descriptor.enumerable = value;\n///      return descriptor;\n///   }\n/// }\n/// ```\npub fn decorators(c: Config) -> impl Pass {\n    if c.legacy {\n        Either::Left(visit_mut_pass(self::legacy::new(c.emit_metadata)))\n    } else {\n        if c.emit_metadata {\n            unimplemented!(\"emitting decorator metadata while using new proposal\")\n        }\n        Either::Right(fold_pass(Decorators {\n            is_in_strict: false,\n            vars: Default::default(),\n        }))\n    }\n}\n\n#[derive(Debug, Default, Deserialize)]\n#[serde(rename_all = \"camelCase\")]\npub struct Config {\n    pub legacy: bool,\n    #[serde(default)]\n    pub emit_metadata: bool,\n\n    pub use_define_for_class_fields: bool,\n}\n","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_ecma_transforms_proposal/src/decorators/mod.rs#L47-L83","documentation":"SWC's decorators pass can only emit decorator metadata (the design:type information used e.g. by NestJS) in legacy-decorator mode. The standard (2022+) proposal path has no metadata story, so constructing the pass with `legacy: false` together with `emitMetadata: true` panics immediately with unimplemented!.","triggerScenarios":"Configuring jsc.decorators as `{ \"legacy\": false, \"emitMetadata\": true }` (or legacy omitted, defaulting to false, with emitMetadata true). The panic happens when the pass is constructed, before any input is read.","commonSituations":"Enabling emitMetadata for NestJS/typedi dependency injection while also trying out the new decorator proposal; copying a Babel config where both flags coexisted; upgrading configs where legacy previously defaulted true.","solutions":["Set \"legacy\": true whenever \"emitMetadata\": true is required (legacy mode supports metadata)","Keep the new proposal only with \"emitMetadata\": false (or omitted)","Remove the decorators config entirely if the project does not use decorators"],"exampleFix":"// before (.swcrc)\n{ \"jsc\": { \"parser\": { \"syntax\": \"typescript\", \"decorators\": true },\n  \"decorators\": { \"legacy\": false, \"emitMetadata\": true } } }\n\n// after\n{ \"jsc\": { \"parser\": { \"syntax\": \"typescript\", \"decorators\": true },\n  \"decorators\": { \"legacy\": true, \"emitMetadata\": true } } }","handlingStrategy":"validation","validationCode":"// Validate decorator config before constructing the pass / spawning swc\nconst d = cfg.jsc?.decorators ?? {};\nif (d.emitMetadata === true && d.legacy !== true) {\n  throw new Error('emitMetadata requires decorators.legacy = true');\n}","typeGuard":"type DecoratorsConfig =\n  | { legacy: true; emitMetadata?: boolean }\n  | { legacy?: false; emitMetadata?: false };\n\nfunction isValid(cfg: DecoratorsConfig): boolean {\n  return cfg.legacy === true || cfg.emitMetadata !== true;\n}","tryCatchPattern":null,"preventionTips":["Treat { legacy: false, emitMetadata: true } as an invalid config in your swcrc loader","Add a config schema check (zod/json-schema) in front of user-provided swc configs","For NestJS-style DI, standardize on legacy: true + emitMetadata: true"],"tags":["swc","decorators","typescript","config","nestjs"],"backgroundTag":"unsupported-feature-combination","analyzedSha":"5176682b65416c6b5de6b47379ae1588ea3ecb3f","analyzedAt":"2026-08-17T16:16:52.067Z","contentChangedAt":"2026-08-17T16:16:52.067Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}