{"record":{"id":"c78bf8890863a40b","repo":"RyanCodrai/turbovec","slug":"invalid-input-value-at-vector-vi-coord-ci-v","errorCode":null,"errorMessage":"invalid input value at vector {vi}, coord {ci}: {v} (must be finite and |value| < 1e16 to avoid f32 norm overflow)","messagePattern":"invalid input value at vector (.+?), coord (.+?): (.+?) \\(must be finite and \\|value\\| < 1e16 to avoid f32 norm overflow\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"turbovec/src/lib.rs","lineNumber":733,"sourceCode":"    /// an error: it is stored with scale 0 and scores 0 against every\n    /// query. See that constant for the rationale.\n    pub fn add(&mut self, vectors: &[f32]) {\n        let dim = self.dim.expect(\n            \"TurboQuantIndex dim is not set; use add_2d(vectors, dim) on the \\\n             first add or construct via TurboQuantIndex::new(dim, bit_width)\",\n        );\n        let n = vectors.len() / dim;\n        assert_eq!(\n            vectors.len(),\n            n * dim,\n            \"vectors length must be a multiple of dim\"\n        );\n        // Empty add is a true no-op.\n        if n == 0 {\n            return;\n        }\n        if let Some((vi, ci, v)) = first_invalid_coord(vectors, dim) {\n            panic!(\n                \"invalid input value at vector {vi}, coord {ci}: {v} \\\n                 (must be finite and |value| < 1e16 to avoid f32 norm overflow)\",\n            );\n        }\n        // One path, always. `add` reads the committed calibration and\n        // never writes one — there is no warm-up buffer, no sample\n        // threshold, and no batch that means more to the encoding than\n        // any other. Whatever this index is calibrated to was set by an\n        // explicit `calibrate` call, so a row's encoded bytes depend on\n        // the row and the calibration and on nothing else: same rows,\n        // same calibration, same bytes, however they were batched and in\n        // whatever order they arrived.\n        self.encode_and_append(vectors, n, dim);\n    }\n\n    /// Test-only switch that makes the next `encode` call panic, so tests\n    /// can exercise the unwind guard below — and the ordering that guard\n    /// depends on (#353). Panics inside `encode` are otherwise only","sourceCodeStart":715,"sourceCodeEnd":751,"githubUrl":"https://github.com/RyanCodrai/turbovec/blob/ccab9f325e6ce2a270a87daf01ae4e443bcf2d49/turbovec/src/lib.rs#L715-L751","documentation":"add() validates every coordinate before ingesting: values must be finite (no NaN/inf) and have magnitude < 1e16, because f32 norm computation would overflow otherwise. The first offending (vector index, coord index, value) is reported and add panics rather than silently corrupting the quantized index.","triggerScenarios":"Calling add() on an index with a vectors buffer containing a NaN, +inf, -inf, or any |value| >= 1e16 at dim-aligned position (vi, ci); empty adds are no-ops and never trigger this.","commonSituations":"Upstream embedding model emitting NaN for degenerate/empty input text; uninitialized memory or zeroed-then-corrupted buffers; mixing f64 intermediate values with huge magnitudes before casting to f32.","solutions":["Sanitize vectors before add: replace NaN/inf and clip values to |v| < 1e16.","Check the embedding pipeline for inputs that produce NaN (empty strings, tokenization failures).","Use a non-panicking add path if available (try_* variant) and handle the error per batch."],"exampleFix":"// before\nindex.add(&raw_vectors); // panics: \"invalid input value at vector 3, coord 7: NaN ...\"\n// after\nlet clean: Vec<f32> = raw_vectors.iter().map(|&v| if v.is_finite() && v.abs() < 1e16 { v } else { 0.0 }).collect();\nindex.add(&clean);","handlingStrategy":"validation","validationCode":"fn sanitize(v: &[f32]) -> Vec<f32> {\n    v.iter().map(|&x| if x.is_finite() && x.abs() < 1e16 { x } else { 0.0 }).collect()\n}","typeGuard":"fn all_valid(v: &[f32]) -> bool {\n    v.iter().all(|x| x.is_finite() && x.abs() < 1e16)\n}","tryCatchPattern":"// panics cannot be caught idiomatically; avoid by validating\nif !all_valid(&vectors) { return Err(AddError::InvalidValue); }\nindex.add(&vectors);","preventionTips":["Sanitize embeddings at the boundary (NaN/inf check) before add.","Trace NaN sources upstream: empty inputs, failed tokenization, huge f64 casts.","Add a debug assertion in pipelines that all vectors are finite."],"tags":["rust","panic","validation","vector-index","numeric"],"backgroundTag":"invalid-argument-value","analyzedSha":"ccab9f325e6ce2a270a87daf01ae4e443bcf2d49","analyzedAt":"2026-09-06T08:39:18.516Z","contentChangedAt":"2026-09-06T08:39:18.516Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}