rollup/rollup · error

not implemented: Cannot convert SimpleAssignTarget::TsNonNul

Error message

not implemented: Cannot convert SimpleAssignTarget::TsNonNull

What it means

convert_simple_assignment_target (converter.rs:700) has an unimplemented! arm at line 719 for SimpleAssignTarget::TsNonNull. This is the assignment-target form of TS's non-null assertion, e.g. `(x!) = value`. SWC parses it but the buffer format cannot represent it, so the converter panics. Assigning to a non-null-asserted expression is almost always a typo.

Source

Thrown at rust/parse_ast/src/convert_ast/converter.rs:720

      SimpleAssignTarget::Ident(binding_identifier) => {
        self.convert_binding_identifier(binding_identifier)
      }
      SimpleAssignTarget::Member(member_expression) => {
        self.convert_member_expression(member_expression, false, false)
      }
      SimpleAssignTarget::SuperProp(super_property) => self.convert_super_property(super_property),
      SimpleAssignTarget::Paren(parenthesized_expression) => {
        self.convert_parenthesized_expression(parenthesized_expression);
      }
      SimpleAssignTarget::OptChain(optional_chain_expression) => {
        self.store_chain_expression(optional_chain_expression, false)
      }
      SimpleAssignTarget::TsAs(_) => unimplemented!("Cannot convert SimpleAssignTarget::TsAs"),
      SimpleAssignTarget::TsSatisfies(_) => {
        unimplemented!("Cannot convert SimpleAssignTarget::TsSatisfies")
      }
      SimpleAssignTarget::TsNonNull(_) => {
        unimplemented!("Cannot convert SimpleAssignTarget::TsNonNull")
      }
      SimpleAssignTarget::TsTypeAssertion(_) => {
        unimplemented!("Cannot convert SimpleAssignTarget::TsTypeAssertion")
      }
      SimpleAssignTarget::TsInstantiation(_) => {
        unimplemented!("Cannot convert SimpleAssignTarget::TsInstantiation")
      }
      SimpleAssignTarget::Invalid(_) => {
        unimplemented!("Cannot convert SimpleAssignTarget::Invalid")
      }
    }
  }

  pub(crate) fn convert_property_name(&mut self, property_name: &PropName) {
    match property_name {
      PropName::Computed(computed_property_name) => {
        self.convert_expression(computed_property_name.expr.as_ref())
      }

View on GitHub (pinned to ddc4ffab62)

Solutions

  1. Rewrite to assign to the underlying reference: `map.set(k, v);` or `el.value = target;`.
  2. Add a TypeScript transform plugin so the `!` is stripped before parsing (then assign to the base).
  3. Remove the stray `!` if it is unintended.

Example fix

// before
(map.get(k)!) = v;

// after
map.set(k, v);
Defensive patterns

Strategy: validation

Validate before calling

// Detect `(x!) =` style assignment targets.
function hasTsNonNullAssignTarget(src) {
  return /\(\s*[A-Za-z_$][\w$]*\s*!\s*\)\s*=/.test(src);
}
if (hasTsNonNullAssignTarget(code)) {
  throw new Error('`(x!) = value` is invalid; assign to the underlying reference.');
}

Try / catch

try {
  await rollup({ input });
} catch (err) {
  if (String(err.message).includes('SimpleAssignTarget::TsNonNull')) {
    throw new Error('A TS non-null assertion is used as an assignment target; rewrite the statement.');
  }
  throw err;
}

Prevention

When it happens

Trigger: Source contains an assignment whose left-hand side carries a non-null assertion, such as `(map.get(k)!) = v` or `(el!) = target`. The SimpleAssignTarget::TsNonNull node reaches convert_simple_assignment_target with no store arm.

Common situations: Misplaced `!` that turns a read into an assignment target. Generated/refactored code. Confusion between `!` (assertion) and a valid assignment target.

Related errors


AI-assisted analysis of rollup/rollup@ddc4ffab62 (2026-08-03). Data as JSON: /data/errors/d480cad3a0e2f7b4.json. Report an issue: GitHub.