vectordotdev/vector · error
No usable integer type should be unrepresentable by both…
Error message
No usable integer type should be unrepresentable by both `u64` and `f64`.
What it means
In vector-config's numeric schema machinery, `get_encoded_zero_value` converts the numeric type's zero into a JSON `Number`, first trying u64 and then f64, and panics if neither representation succeeds. Every supported integer type (u8..u64, i8..i64, etc.) must have its zero representable in one of these formats, so failure indicates an unsupported numeric implementation was wired into the Configurable trait. It is a pure internal invariant panic.
Solutions
- Ensure the type's `Numeric` associated type correctly implements num_traits::ToPrimitive so to_u64()/to_f64() succeed for zero
- Verify the type is registered via the standard macro so it maps to a supported primitive, not a custom adapter
- Write a unit test calling get_encoded_zero_value for every numeric type to catch regressions
Example fix
// before
zero_num_unsigned.or(zero_num_floating)
.expect("No usable integer type should be unrepresentable by both `u64` and `f64`.")
// after
zero_num_unsigned.or(zero_num_floating).unwrap_or(serde_json::Number::from(0u64)) Defensive patterns
Strategy: validation
Validate before calling
// Verify the numeric type converts before invoking schema generation: let zero = <T as ConfigurableNum>::Numeric::zero(); assert!(zero.to_u64().is_some() || zero.to_f64().is_some());
Type guard
fn has_representable_zero<N: ToPrimitive>(n: &N) -> bool {
n.to_u64().is_some() || n.to_f64().is_some()
} Prevention
- Only wire standard primitives (u8-u64, i8-i64, f32/f64) into the Configurable numeric machinery
- Implement ToPrimitive fully on any custom numeric adapter
- Add a per-type unit test for get_encoded_zero_value
When it happens
Trigger: Calling `get_encoded_zero_value()` on a Configurable numeric type whose `Numeric` zero conversion via num_traits ToPrimitive returns None from both to_u64 and to_f64 — i.e. a custom numeric type that does not properly implement ToPrimitive.
Common situations: Adding a new numeric type to the Configurable machinery with a broken or partial ToPrimitive implementation; custom wrapper types over Num that fail zero() conversions.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- already found inputs
- `Configurable` does not support numbers larger than an…
- metadata extension must always be a map
- registered log schema required
- source output misconfigured
AI-assisted analysis of vectordotdev/vector@bdb87aeaa4 (2026-09-16).
Data as JSON: /api/errors/b4d25c0778f1fcbe.
Report an issue: GitHub.
Appendix: source
Thrown at lib/vector-config/src/num.rs:75
}
/// Whether or not a generated schema for this numeric type must explicitly disallow zero values.
///
/// In some cases, such as `NonZero*` types from `std::num`, a numeric type may not support zero values for reasons
/// of correctness and/or optimization. In some cases, we can simply adjust the normal minimum/maximum bounds in the
/// schema to encode this. In other cases, such as signed versions like `NonZeroI64`, zero is a discrete value
/// within the minimum and maximum bounds and must be excluded explicitly.
fn requires_nonzero_exclusion() -> bool {
false
}
/// Gets the JSON encoded version of the zero value for the integral numeric type.
fn get_encoded_zero_value() -> Number {
let zero_num_unsigned = Self::Numeric::zero().to_u64().map(Into::into);
let zero_num_floating = Self::Numeric::zero().to_f64().and_then(Number::from_f64);
zero_num_unsigned
.or(zero_num_floating)
.expect("No usable integer type should be unrepresentable by both `u64` and `f64`.")
}
/// Gets the minimum bound for this numeric type, limited by the representable range in JSON Schema.
fn get_enforced_min_bound() -> f64 {
let mechanical_minimum = match (Self::is_nonzero(), Self::requires_nonzero_exclusion()) {
// If the number is not a nonzero type, or it is a nonzero type, but needs an exclusion, we simply return
// its true mechanical minimum bound. For nonzero types, this is because we can only enforce the nonzero
// constraint through a negative schema bound, not through its normal minimum/maximum bounds validation.
(false, _) | (true, true) => Self::Numeric::min_value(),
// If the number is a nonzero type, but does not need an exclusion, its minimum bound is always 1.
(true, false) => Self::Numeric::one(),
};
let enforced_minimum = NUMERIC_ENFORCED_LOWER_BOUND;
let mechanical_minimum = mechanical_minimum
.to_f64()
.expect("`Configurable` does not support numbers larger than an `f64` representation");
View on GitHub (pinned to bdb87aeaa4)