swc-project/swc · error

Please confirm if plugin macro is specified for the function

Error message

Please confirm if plugin macro is specified for the function

What it means

#[plugin_transform] is the attribute proc macro from swc_plugin_macro that wraps a SWC plugin's WASM transform entry point. It parses the annotated item with syn and only accepts an ItemFn (see the `SynItem::Fn(func)` arm); any other item kind makes the macro panic at compile time with this message.

Source

Thrown at crates/swc_plugin_macro/src/lib.rs:16

extern crate proc_macro;
use proc_macro::TokenStream;
use proc_macro2::{Ident, Span};
use quote::quote;
use syn::{Item as SynItem, ItemFn};

#[proc_macro_attribute]
pub fn plugin_transform(
    _args: proc_macro::TokenStream,
    input: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
    let token = proc_macro2::TokenStream::from(input);
    let parsed_results = syn::parse2::<SynItem>(token).expect("Failed to parse tokens");
    match parsed_results {
        SynItem::Fn(func) => handle_func(func, Ident::new("Program", Span::call_site())),
        _ => panic!("Please confirm if plugin macro is specified for the function"),
    }
}

#[allow(clippy::redundant_clone)]
fn handle_func(func: ItemFn, ast_type: Ident) -> TokenStream {
    let ident = func.sig.ident.clone();
    let transform_process_impl_ident =
        Ident::new("__transform_plugin_process_impl", Span::call_site());
    let transform_core_pkg_diag_ident =
        Ident::new("__get_transform_plugin_core_pkg_diag", Span::call_site());

    let ret = quote! {
        #func

        // Declaration for imported function from swc host.
        // Refer swc_plugin_runner for the actual implementation.
        #[cfg(target_arch = "wasm32")] // Allow testing
        #[link(wasm_import_module = "env")]

View on GitHub (pinned to 5176682b65)

Solutions

  1. Move #[plugin_transform] so it decorates the plugin's transform function itself, with no other item between
  2. Give that function the required plugin signature: fn process(program: &mut Program, metadata: TransformPluginContextMetadata, config: String, should_enable_comments_proxy: bool, ast: &AstNode<PathBuf>) -> Program
  3. Delete stray copies of the attribute from structs/impls/modules and run `cargo check --target wasm32-wasip1` to confirm the macro expands

Example fix

// before
#[plugin_transform]
pub struct Config { pub opt: bool } // proc macro panics: not a function

// after
pub struct Config { pub opt: bool }

#[plugin_transform]
pub fn process_transform(
    program: &mut Program,
    _metadata: TransformPluginContextMetadata,
    _config: String,
    _should_enable_comments_proxy: bool,
    _ast: &AstNode<PathBuf>,
) -> Program {
    program.clone()
}
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: Applying #[plugin_transform] to anything other than a free function: a struct (e.g. a config struct), an impl block, a module, a trait, or a use item. Also happens when the attribute is left on an outer item after refactoring moved the transform fn elsewhere.

Common situations: Bootstrapping a plugin from a modified `swc plugin new` template; splitting the transform into helper items and accidentally relocating the attribute; copy-pasting the attribute above config/state types.

Related errors


AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17). Data as JSON: /api/errors/e021cb72eca6c558. Report an issue: GitHub.