swc-project/swc · error

Cannot use both #[encoding(with)] and #[encoding(ignore)] at

Error message

Cannot use both #[encoding(with)] and #[encoding(ignore)] attributes on the same field

What it means

The Decode derive from swc's ast_node crate (re-exported as swc_common::Decode and applied by #[ast_node] under the encoding-impl feature) generates CBOR decoding via cbor4ii. While expanding a struct it maps each field's #[encoding(...)] attributes: `with = "Path"` delegates decoding to a wrapper type, and `ignore` substitutes Default::default(). The two are mutually exclusive per field; carrying both makes the attribute match hit the (Some(_), true) arm and panic during macro expansion, failing the build.

Source

Thrown at crates/ast_node/src/encoding/decode.rs:30

                .enumerate()
                .map(|(idx, field)| match field.ident.as_ref() {
                    Some(name) => name.clone(),
                    None => {
                        let name = format!("unit{idx}");
                        syn::Ident::new(&name, field.span())
                    }
                })
                .collect::<Vec<_>>();

            let fields = data.fields.iter()
                .zip(names.iter())
                .map(|(field, field_name)| -> syn::Stmt {
                    let ty = &field.ty;
                    let value: syn::Expr = match (is_with(&field.attrs), is_ignore(&field.attrs)) {
                        (Some(with_type), false) => syn::parse_quote!(<#with_type<#ty> as cbor4ii::core::dec::Decode<'_>>::decode(reader)?.0),
                        (None, false) => syn::parse_quote!(<#ty as cbor4ii::core::dec::Decode<'_>>::decode(reader)?),
                        (None, true) => syn::parse_quote!(<#ty as Default>::default()),
                        (Some(_), true) => panic!("Cannot use both #[encoding(with)] and #[encoding(ignore)] attributes on the same field")
                    };

                    syn::parse_quote!{
                        let #field_name = #value;
                    }
                });
            let build_struct: syn::Expr = if is_named {
                syn::parse_quote! { #ident { #(#names),* } }
            } else {
                syn::parse_quote! { #ident ( #(#names),* ) }
            };

            let count = data
                .fields
                .iter()
                .filter(|field| !is_ignore(&field.attrs))
                .count();
            let head: Option<syn::Stmt> = (count != 1).then(|| {

View on GitHub (pinned to 5176682b65)

Solutions

  1. Pick one behavior per field: keep #[encoding(ignore)] to skip the field (decoded as Default), or #[encoding(with = "...")] to use the custom codec, and delete the other.
  2. If the field should sometimes default, implement that inside the with-type's Decode impl instead of stacking attributes.

Example fix

// before
#[derive(Encode, Decode)]
pub struct Node {
    #[encoding(with = "IdAsText")]
    #[encoding(ignore)]
    pub id: u32,
}

// after — drop the conflicting codec, keep ignore
#[derive(Encode, Decode)]
pub struct Node {
    #[encoding(ignore)]
    pub id: u32,
}
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: Deriving Decode (directly or via #[ast_node] with the encoding-impl feature) on a struct where one field has both #[encoding(with = "SomeCodec")] and #[encoding(ignore)] — whether combined in one attribute (#[encoding(with = "SomeCodec", ignore)]) or split across two #[encoding(...)] attributes on that field.

Common situations: Copy-pasting AST node definitions while toggling codec behavior; merging upstream swc_ecma_ast changes where a field switched from encoded to ignored and both attributes survived the merge.

Related errors


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