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

  1. Set `jsc.transform.legacyDecorator: true` — metadata emission is supported in legacy mode
  2. Or disable `jsc.transform.decoratorMetadata` and stay on the modern proposal
  3. 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

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


AI-assisted analysis of swc-project/swc@d7d7434666 (2026-08-16). Data as JSON: /api/errors/7d56cad8b02eac5d. Report an issue: GitHub.