influxdata/influxdb · error · syn::Error
` ` must have exactly one type parameter
Error message
`{name}` must have exactly one type parameter What it means
A compile-time error from the catalog record field-type checker. Whitelisted container types (those in `CONTAINERS`) must carry exactly one type argument, and that argument must itself be a type (not a lifetime or const). Zero, multiple, or non-type arguments make the persisted shape ambiguous, so `check_path` rejects them before recursing into the single inner type.
Solutions
- Write the container with exactly one type argument: `Option<T>` or `Vec<T>`.
- If extra parameters (allocator, capacity) are needed, drop them or encode the fixed layout in a dedicated wire type in `records::types`.
Example fix
// before
#[catalog_record(shape = 0x1)]
struct Foo { items: Vec<u64, CustomAlloc> }
// after
#[catalog_record(shape = 0x1)]
struct Foo { items: Vec<u64> } Defensive patterns
Strategy: validation
Validate before calling
// Containers must have exactly one type argument: // OK: Vec<u64>, Option<String> // NOT OK: Vec<u64, Alloc>, Option<>
Prevention
- Always write Option<T> / Vec<T> with a single type argument.
- Drop allocator or capacity parameters from container field types.
- Encode fixed-size layouts with const-literal types (e.g. Reserved<16>) if needed.
When it happens
Trigger: Declaring a field like `field: Option<>` (empty), `field: Vec<u64, Alloc>` (two arguments), or `field: Option<'a T>`-style arguments where the inner-type filter yields a count that isn't exactly 1. Raised in `check_path` when `inner.len() != 1`.
Common situations: A developer writes a container with a custom allocator/capacity parameter, or leaves an incomplete generic argument while editing.
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…
- ` ` is generic. Only may take type parameters in a catalog…
- 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/e1f3baa57a8b9981.
Report an issue: GitHub.
Appendix: source
Thrown at influxdb3_catalog_macros/src/types.rs:86
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();
if inner.len() != args.args.len() || inner.len() != 1 {
return Err(syn::Error::new(
ty.span(),
format!("`{name}` must have exactly one type parameter"),
));
}
check(inner[0])
}
PathArguments::AngleBracketed(_) | PathArguments::Parenthesized(_) => Err(unsupported(ty)),
}
}
/// Whether a generic argument is a const *literal*, the only generic argument
/// permitted outside `Option`/`Vec`. See the call site for why.
fn is_const_literal(arg: &GenericArgument) -> bool {
matches!(
arg,
GenericArgument::Const(syn::Expr::Lit(syn::ExprLit {
lit: syn::Lit::Int(_),
..View on GitHub (pinned to 06200ef96b)