swc-project/swc · error
emitting decorator metadata while using new proposal
Error message
emitting decorator metadata while using new proposal
What it means
The decorator pass supports two modes: legacy decorators (with optional metadata emission via `legacy::new(c.emit_metadata)`) and the 2022-03 spec transform, which has no metadata story in swc. Constructing the pass with `legacy: false` and `emit_metadata: true` hits `unimplemented!` at pass-construction time.
Source
Thrown at crates/swc_ecma_transforms_proposal/src/decorators/mod.rs:65
/// ```js
/// class C {
/// @enumerable(false)
/// method() { }
/// }
///
/// function enumerable(value) {
/// return function (target, key, descriptor) {
/// descriptor.enumerable = value;
/// return descriptor;
/// }
/// }
/// ```
pub fn decorators(c: Config) -> impl Pass {
if c.legacy {
Either::Left(visit_mut_pass(self::legacy::new(c.emit_metadata)))
} else {
if c.emit_metadata {
unimplemented!("emitting decorator metadata while using new proposal")
}
Either::Right(fold_pass(Decorators {
is_in_strict: false,
vars: Default::default(),
}))
}
}
#[derive(Debug, Default, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Config {
pub legacy: bool,
#[serde(default)]
pub emit_metadata: bool,
pub use_define_for_class_fields: bool,
}
View on GitHub (pinned to d7d7434666)
Solutions
- Set `jsc.transform.legacyDecorator: true` — metadata emission is supported in legacy mode
- Or disable `jsc.transform.decoratorMetadata` and stay on the modern proposal
- If you must stay on the new proposal, emit metadata in a follow-up pass of your own
Example fix
// .swcrc before
{ "jsc": { "transform": { "legacyDecorator": false, "decoratorMetadata": true } } }
// after
{ "jsc": { "transform": { "legacyDecorator": true, "decoratorMetadata": true } } } Defensive patterns
Strategy: validation
Validate before calling
// Reject the unsupported combination before compiling
const t = cfg.jsc?.transform ?? {};
if (t.decoratorMetadata === true && t.legacyDecorator === false) {
throw new Error('decoratorMetadata requires legacyDecorator: true in swc');
} Prevention
- Treat `decoratorMetadata: true` as implying `legacyDecorator: true` in your config loader
- Mirror TypeScript's rule: no `emitDecoratorMetadata` without `experimentalDecorators`
When it happens
Trigger: Configure decorators with `jsc.parser.decorators: true`, `jsc.transform.legacyDecorator: false` and `jsc.transform.decoratorMetadata: true` (swc core maps these fields onto the Config struct in decorators/mod.rs).
Common situations: Migrating off `experimentalDecorators` in TypeScript while keeping `emitDecoratorMetadata: true` (TS itself warns this combination is unsupported); porting Babel configs that set decorators + decoratorMetadata without the legacy flag; NestJS-style codebases trying the new proposal.
Related errors
- ClassMember::{:?}
- derive(Merge) does not support an enum
- codegen of `export default from 'foo';`
- corejs version other than 2 / 3
- determine_export_name({:?})
AI-assisted analysis of swc-project/swc@d7d7434666 (2026-08-16).
Data as JSON: /api/errors/7d56cad8b02eac5d.
Report an issue: GitHub.