influxdata/influxdb · error · syn::Error
` ` is generic. Only may take type parameters in a catalog…
Error message
`{name}` is generic. Only {} may take type parameters in a catalog record, and any other generic must be parameterised solely by const literals (e.g. `Reserved<16>`); a generic body has no single persisted shape. What it means
A compile-time error from the catalog record field-type checker. A field type may carry generic parameters only if it is one of the whitelisted CONTAINERS (e.g. `Option`, `Vec`) or if every parameter is a const literal (like `Reserved<16>`); anything else is rejected because a generic body has no single persisted shape the fingerprint can describe.
Solutions
- Replace the generic type with a whitelisted container (`Option`, `Vec`) over allowed primitives, or a const-literal-parameterized type like `Reserved<16>`.
- Define a concrete (non-generic) wire type in `records::types` for the data and convert to the runtime type in `apply`.
Example fix
// before
#[catalog_record(shape = 0x1)]
struct Foo { tags: HashMap<String, u64> }
// after
#[catalog_record(shape = 0x1)]
struct Foo { tags: Vec<(String, u64)> } Defensive patterns
Strategy: validation
Validate before calling
// Only allow generics on whitelisted containers or const literals: // OK: Option<u64>, Vec<String>, Reserved<16> // NOT OK: MyWrapper<u64>, HashMap<String, u64>
Prevention
- Restrict record fields to Option/Vec containers or const-literal generics like Reserved<16>.
- Do not put maps or custom generic collections directly in records.
- Model complex data as concrete wire types in records::types.
When it happens
Trigger: Declaring a catalog record field like `field: MyWrapper<u64>` or `field: HashMap<String, u64>` where the name is not in `CONTAINERS` and the arguments are type (not const) parameters. Raised in `check_path` when const-literal check fails and the container check fails.
Common situations: A developer tries to store a map or a custom generic collection directly in a record, or parameterizes a helper type over a runtime type.
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…
- ` ` must have exactly one type parameter
- catalog records must be structs with named fields
- ⚠ Field shape of catalog record
- ` ` is a qualified path. A catalog record may only hold…
AI-assisted analysis of influxdata/influxdb@06200ef96b (2026-09-19).
Data as JSON: /api/errors/017835f100d73615.
Report an issue: GitHub.
Appendix: source
Thrown at influxdb3_catalog_macros/src/types.rs:66
match &segment.arguments {
PathArguments::None => Ok(()),
// Every argument a const literal, e.g. `Reserved<16>`. Permitted where
// a type parameter is not: the objection to a generic body is that it
// has no single persisted shape, and a const argument does have one.
// Each instantiation is also a distinct token sequence, so the shape
// fingerprint tells `Reserved<16>` from `Reserved<32>` and a change of
// width cannot slip through as compatible.
//
// Literals only. A named constant would fingerprint by name, so two
// names for one width would disagree and renaming a constant would
// move the shape without moving a byte.
PathArguments::AngleBracketed(args) if !args.args.is_empty() => {
if args.args.iter().all(is_const_literal) {
return Ok(());
}
if !CONTAINERS.contains(&name.as_str()) {
return Err(syn::Error::new(
ty.span(),
format!(
"`{name}` is generic. Only {} may take type parameters in a catalog \
record, and any other generic must be parameterised solely by const \
literals (e.g. `Reserved<16>`); a generic body has no single persisted \
shape.",
CONTAINERS.join(" and ")
),
));
}
let inner: Vec<&Type> = args
.args
.iter()
.filter_map(|arg| match arg {
GenericArgument::Type(t) => Some(t),
_ => None,
})
.collect();View on GitHub (pinned to 06200ef96b)