RyanCodrai/turbovec · error · io::Error
invalid TQ+ shift at coord {i}: {v} (must be finite and |shi
Error message
invalid TQ+ shift at coord {i}: {v} (must be finite and |shift| <= {:e} at dim {}) What it means
validate_calibration rejects TQ+ calibration shift vectors containing non-finite values (NaN/Inf) or magnitudes exceeding max_tqplus_shift(dim) for the given dimension. The bound exists because the shift is applied per coordinate during search; unbounded shifts would destroy score ordering. The error pinpoints the offending coordinate index, value, bound, and dimension.
Source
Thrown at turbovec/src/io.rs:580
pub(crate) const MAX_VECTOR_SCALE: f32 = 1e22;
/// Value-level calibration validation — THE rule, shared by every
/// loader (v6 here, v7 in `io_v7`): the encoder only ever emits finite
/// shifts and strictly-positive scales, so anything else is corruption
/// or an attacker payload. Search divides by `tqplus_scale`, so a
/// zero/negative/non-finite value — which a bare is_finite() check
/// would not fully catch — silently turns every query's scores into
/// NaN/Inf.
pub(crate) fn validate_calibration(
tqplus_shift: &[f32],
tqplus_scale: &[f32],
) -> io::Result<()> {
if let Some((i, &v)) = tqplus_shift
.iter()
.enumerate()
.find(|(_, v)| !v.is_finite() || v.abs() > max_tqplus_shift(tqplus_shift.len()))
{
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!(
"invalid TQ+ shift at coord {i}: {v} (must be finite and \
|shift| <= {:e} at dim {})",
max_tqplus_shift(tqplus_shift.len()),
tqplus_shift.len()
),
));
}
if let Some((i, &v)) = tqplus_scale
.iter()
.enumerate()
.find(|(_, v)| !v.is_finite() || **v < min_tqplus_scale(tqplus_scale.len()))
{
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!(
"invalid TQ+ scale at coord {i}: {v} (must be finite and \View on GitHub (pinned to ccab9f325e)
Solutions
- Clamp each shift to the allowed bound max_tqplus_shift(dim) before saving/loading
- Replace NaN/Inf entries with finite values or recompute the calibration
- Check the calibration training pipeline for numerical overflow
- Reduce per-coordinate shift magnitudes or rescale the embedding space
Example fix
// before cal.tqplus_shift = raw_shifts; // may contain 1e400 // after let lim = max_tqplus_shift(raw_shifts.len()); cal.tqplus_shift = raw_shifts.iter().map(|&v| v.clamp(-lim, lim)).collect();
Defensive patterns
Strategy: validation
Validate before calling
let lim = turbovec::max_tqplus_shift(shift.len());
assert!(shift.iter().all(|&v| v.is_finite() && v.abs() <= lim),
"TQ+ shift out of range (limit {lim:e})"); Type guard
fn shift_valid(s: &[f64]) -> bool {
let lim = turbovec::max_tqplus_shift(s.len());
s.iter().all(|&v| v.is_finite() && v.abs() <= lim)
} Try / catch
match validate_calibration(&cal) {
Err(e) if e.to_string().contains("invalid TQ+ shift") => {
eprintln!("calibration rejected: {e}; recomputing");
cal.tqplus_shift = recompute_shifts();
}
other => other?,
} Prevention
- Clamp shifts to max_tqplus_shift(dim) right after fitting
- Assert finiteness of calibration arrays in unit tests
- Sanity-check any calibration imported from external tools
When it happens
Trigger: Loading or saving a calibration (via the v7 image or calibrate API) whose tqplus_shift slice contains NaN, Inf, or a value whose absolute value exceeds the dimension-dependent limit max_tqplus_shift(len).
Common situations: Hand-editing calibration parameters; producing shifts from a numerically unstable training run; deserializing calibrations from another tool without range checks.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- invalid TQ+ scale at coord {i}: {v} (must be finite and >= {
- duplicate id in batch: {k!r}
- {prefix} {version}; this turbovec accepts versions {list(com
- persisted store is corrupt: {len(extraneous)} {what} id(s) p
- {param} must be one of {list(_VALID_MODES)}, got {value!r}
AI-assisted analysis of RyanCodrai/turbovec@ccab9f325e (2026-09-06).
Data as JSON: /api/errors/09d284efce1f176e.
Report an issue: GitHub.