RyanCodrai/turbovec · error · io::Error

invalid TQ+ scale at coord {i}: {v} (must be finite and >= {

Error message

invalid TQ+ scale at coord {i}: {v} (must be finite and >= {:e} at dim {}; search divides by it and sums across every coordinate, so a smaller value turns every score into Inf/NaN)

What it means

validate_calibration rejects TQ+ scale vectors that are non-finite or below min_tqplus_scale(dim). Because search divides by the scale and sums across every coordinate, too-small (or zero/negative) values turn every score into Inf/NaN, so the library refuses the calibration up front. The message names the offending coordinate, value, minimum, and dimension.

Source

Thrown at turbovec/src/io.rs:595

        .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 \
                 >= {:e} at dim {}; search divides by it and sums across \
                 every coordinate, so a smaller value turns every score \
                 into Inf/NaN)",
                min_tqplus_scale(tqplus_scale.len()),
                tqplus_scale.len()
            ),
        ));
    }
    Ok(())
}




View on GitHub (pinned to ccab9f325e)

Solutions

  1. Set every scale coordinate to at least min_tqplus_scale(dim) (e.g. clamp or floor it)
  2. Recompute the calibration if scales underflowed to zero
  3. Reject/repair zero- or NaN-filled scales before persisting
  4. Verify the calibration training converges before exporting

Example fix

// before
cal.tqplus_scale = fitted_scales; // some entries 0.0
// after
let floor = min_tqplus_scale(fitted_scales.len());
cal.tqplus_scale = fitted_scales.iter().map(|&v| v.max(floor)).collect();
Defensive patterns

Strategy: validation

Validate before calling

let floor = turbovec::min_tqplus_scale(scale.len());
assert!(scale.iter().all(|&v| v.is_finite() && v >= floor),
        "TQ+ scale below {floor:e}");

Type guard

fn scale_valid(s: &[f64]) -> bool {
    let floor = turbovec::min_tqplus_scale(s.len());
    s.iter().all(|&v| v.is_finite() && v >= floor)
}

Try / catch

match validate_calibration(&cal) {
    Err(e) if e.to_string().contains("invalid TQ+ scale") => {
        eprintln!("calibration rejected: {e}; flooring scales");
        let floor = turbovec::min_tqplus_scale(cal.tqplus_scale.len());
        for v in &mut cal.tqplus_scale { *v = v.max(floor); }
    }
    other => other?,
}

Prevention

When it happens

Trigger: Loading/saving a calibration whose tqplus_scale slice contains NaN, Inf, or a value < min_tqplus_scale(len), typically via calibrate or v7 file load.

Common situations: Zero-initialized scale arrays left untrained; numerical underflow in calibration fitting; importing calibrations from external tools without sanity 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


AI-assisted analysis of RyanCodrai/turbovec@ccab9f325e (2026-09-06). Data as JSON: /api/errors/488d46f7a3634d53. Report an issue: GitHub.