influxdata/influxdb · error · syn::Error

duplicate `shape`

Error message

duplicate `shape`

What it means

Compile-time error from the influxdb3_catalog_macros attribute parser: the `shape = <int>` key was supplied more than once in the macro invocation attributes. The parser walks name-value pairs and stores each in an Option; a second occurrence finds it already set and aborts with this syn::Error at the duplicate key's span. It is a validation guard over macro input syntax, raised during procedural-macro expansion (as exercised by tests like flags_default_to_none and err). Fix by keeping a single `shape` entry.

Solutions

  1. Delete the extra `shape = ...` entry, keeping the correct one
  2. Ensure exactly one shape literal per attribute

Example fix

// before
#[catalog(id = record_ids::X, shape = 0x1, shape = 0xbba17476)]
// after
#[catalog(id = record_ids::X, shape = 0xbba17476)]
Defensive patterns

Strategy: validation

Validate before calling

// Exactly one shape argument per attribute:
// bad:  #[catalog(id = X, shape = 0x1, shape = 0x2)]
// good: #[catalog(id = X, shape = 0x2)]

Prevention

When it happens

Trigger: Writing `#[catalog(id = ..., shape = 0x1, shape = 0x2)]`.

Common situations: Merging examples; pasting a corrected shape without deleting the old placeholder line; code generation emitting shape twice.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of influxdata/influxdb@06200ef96b (2026-09-19). Data as JSON: /api/errors/c4fd305fb3c27d4c. Report an issue: GitHub.

Appendix: source

Thrown at influxdb3_catalog_macros/src/lib.rs:110

                "id" => {
                    if id.replace(nv.value).is_some() {
                        return Err(syn::Error::new(nv.path.span(), "duplicate `id`"));
                    }
                }
                "shape" => {
                    let span = nv.value.span();
                    let Expr::Lit(syn::ExprLit {
                        lit: syn::Lit::Int(lit),
                        ..
                    }) = nv.value
                    else {
                        return Err(syn::Error::new(
                            span,
                            "`shape` must be an integer literal, e.g. `shape = 0xbba17476`",
                        ));
                    };
                    if shape.replace(lit).is_some() {
                        return Err(syn::Error::new(nv.path.span(), "duplicate `shape`"));
                    }
                }
                "flags" => {
                    if flags.replace(nv.value).is_some() {
                        return Err(syn::Error::new(nv.path.span(), "duplicate `flags`"));
                    }
                }
                other => {
                    return Err(syn::Error::new(
                        nv.path.span(),
                        format!(
                            "unknown argument `{other}`; supported arguments are `id`, `shape`, `flags`"
                        ),
                    ));
                }
            }
        }

View on GitHub (pinned to 06200ef96b)