swc-project/swc · error · TypeError
Expected '${name}' to be a function
Error message
Expected '${name}' to be a function What it means
The #[proc_macro_derive(Spanned)] entry point parses the incoming TokenStream as a syn::DeriveInput and unwraps with .expect("failed to parse input as DeriveInput"). rustc only feeds derive macros with the AST of the annotated item, so in normal builds this never fails; if it does, the token stream handed to the macro was not a valid derive target (struct/enum/union item), and the proc macro panics with 'proc-macro panicked' plus this message.
Source
Thrown at crates/swc_ecma_transforms_base/src/helpers/generated/_decorate.rs:257
throw new TypeError("A class descriptor's .kind property must be \"class\", but a decorator" + " created a class descriptor with .kind \"" + kind + "\"");
}
_disallowProperty(obj, "key", "A class descriptor");
_disallowProperty(obj, "placement", "A class descriptor");
_disallowProperty(obj, "descriptor", "A class descriptor");
_disallowProperty(obj, "initializer", "A class descriptor");
_disallowProperty(obj, "extras", "A class descriptor");
var finisher = _optionalCallableProperty(obj, "finisher");
var elements = _toElementDescriptors(obj.elements);
return { elements: elements, finisher: finisher };
}
function _disallowProperty(obj, name, objectType) {
if (obj[name] !== undefined) throw new TypeError(objectType + " can't have a ." + name + " property.");
}
function _optionalCallableProperty(obj, name) {
var value = obj[name];
if (value !== undefined && typeof value !== "function") {
throw new TypeError("Expected '" + name + "' to be a function");
}
return value;
}
function _runClassFinishers(constructor, finishers) {
for (var i = 0; i < finishers.length; i++) {
var newConstructor = (0, finishers[i])(constructor);
if (newConstructor !== undefined) {
if (typeof newConstructor !== "function") throw new TypeError("Finishers must return a constructor.");
constructor = newConstructor;
}
}
return constructor;
}
"#,
#[cfg(feature = "inline-helpers")]
deps: super::HelperBitmap::from_bits(0x0000000601a000044000080000000018),View on GitHub (pinned to 5176682b65)
Solutions
- Confirm #[derive(Spanned)] from swc is placed on a plain struct/enum/union definition with valid syntax (let rustc's own parse errors surface first - fix any preceding syntax errors in the item).
- If the item is macro-generated, expand the outer macro (cargo expand) and check the emitted item is a well-formed struct/enum/union.
- Check for duplicate/conflicting derives or attributes that rewrite the item before derivation.
- If it persists on valid code, report it to the swc repo with the item source and rustc/cargo versions.
Defensive patterns
Strategy: validation
Prevention
- Place #[derive(Spanned)] only on ordinary struct/enum/union items that already compile without the derive.
- When the item comes from another macro, expand it (cargo expand) to confirm it is a plain item before adding derives.
When it happens
Trigger: Using #[derive(Spanned)] on something that is not a plain item (e.g. inside macro-generated code whose expansion is not a valid DeriveInput), invoking the macro directly with raw tokens (macro playgrounds, quote-and-invoke tooling), or a syn version mismatch between the macro crate and what produced the tokens.
Common situations: Almost always a tooling/implementation accident rather than user code: nightly vs stable parser differences, third-party crates re-exporting the derive with incompatible syn versions, or test harnesses that call proc macros with hand-built token streams.
Related errors
- An element descriptor's .kind property must be either "metho
- An element descriptor's .placement property must be one of "
- A class descriptor's .kind property must be "class", but a d
- ${objectType} can't have a .${name} property.
- Finishers must return a constructor.
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/dded5689bbdd91ac.
Report an issue: GitHub.