influxdata/influxdb · error · syn::Error
catalog records must be structs with named fields
Error message
catalog records must be structs with named fields
What it means
A compile-time error from the `#[catalog_record]` proc-macro. The macro only supports structs whose fields are all named (`struct Foo { a: u64 }`), because it reads field types in order to compute the persisted-shape fingerprint and generates code that accesses fields by name. Tuple structs, unit structs, and enum inputs are rejected.
Solutions
- Convert the struct to use named fields (e.g. `struct Foo(u64)` becomes `struct Foo { field0: u64 }`).
- If a newtype is desired, wrap it inside a named-field record struct instead.
- Recompute the `shape` fingerprint after restructuring fields, since field order/types feed the fingerprint.
Example fix
// before
#[catalog_record(shape = 0x1234)]
struct Foo(u64);
// after
#[catalog_record(shape = 0x5678)]
struct Foo { id: u64 } Defensive patterns
Strategy: validation
Validate before calling
// Ensure the record struct uses named fields before applying the macro:
// struct Foo { id: u64 } // OK
// struct Foo(u64); // NOT OK Prevention
- Always declare catalog records with named fields.
- Avoid newtype/tuple-struct wrappers as records; wrap inside a named-field record.
- Recompute the shape fingerprint when restructuring fields.
When it happens
Trigger: Applying `#[catalog_record(...)]` to a tuple struct (`struct Foo(u64)`), a unit struct (`struct Foo;`), or any non-struct item with unnamed fields. Raised in `expand` at the `let Fields::Named(ref fields) = item.fields else` branch.
Common situations: A developer models a record as a newtype wrapper or tuple struct for brevity, or ports a type from another serialization framework that allowed tuple structs.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- catalog records cannot be generic — the persisted bytes…
- ⚠ Field shape of catalog record
- ` ` is a qualified path. A catalog record may only hold…
- ` ` is not allowed in a catalog record. Fields may be…
- ` ` is generic. Only may take type parameters in a catalog…
AI-assisted analysis of influxdata/influxdb@06200ef96b (2026-09-19).
Data as JSON: /api/errors/cf1a87319a9cb7be.
Report an issue: GitHub.
Appendix: source
Thrown at influxdb3_catalog_macros/src/lib.rs:162
shape: shape.base10_parse()?,
shape_span: shape.span(),
flags,
})
}
}
fn expand(metas: Punctuated<Meta, Token![,]>, item: ItemStruct) -> syn::Result<TokenStream2> {
let args = Args::parse(metas)?;
if !item.generics.params.is_empty() {
return Err(syn::Error::new(
item.generics.span(),
"catalog records cannot be generic — the persisted bytes must be one fixed shape",
));
}
let Fields::Named(ref fields) = item.fields else {
return Err(syn::Error::new(
item.fields.span(),
"catalog records must be structs with named fields",
));
};
let field_types: Vec<&Type> = fields.named.iter().map(|f| &f.ty).collect();
for ty in &field_types {
types::check(ty)?;
}
let actual = shape::fingerprint(&field_types);
if actual != args.shape {
return Err(syn::Error::new(
args.shape_span,
shape_mismatch_message(&item.ident, args.shape, actual),
));
}
View on GitHub (pinned to 06200ef96b)