{"record":{"id":"e84aac4e50b5ae9d","repo":"RyanCodrai/turbovec","slug":"ids-for-rows","errorCode":null,"errorMessage":"{} ids for {} rows","messagePattern":"(.+?) ids for (.+?) rows","errorType":"validation","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"turbovec/src/id_map.rs","lineNumber":904,"sourceCode":"        let l = crate::io_v7::load(path, 0, 1)?;\n        // See TurboQuantIndex::load_v7 — an unclaimed snapshot loads\n        // unbound so the first sync claims it.\n        let bind = (l.cursor.nonce != crate::io_v7::UNCLAIMED_NONCE).then_some(path);\n        Self::from_v7_load(l, bind)\n    }\n\n    /// Wrap an already-built index with an id table.\n    ///\n    /// Used by [`crate::convert`], which decodes a file into codes plus\n    /// ids and needs to re-emit it: the ids are validated for duplicates\n    /// exactly as a load does, since a table with a repeat cannot answer\n    /// `remove` or `contains` unambiguously.\n    pub(crate) fn from_index_and_ids(\n        inner: TurboQuantIndex,\n        slot_to_id: Vec<u64>,\n    ) -> std::io::Result<Self> {\n        if slot_to_id.len() != inner.len() {\n            return Err(std::io::Error::new(\n                std::io::ErrorKind::InvalidData,\n                format!(\"{} ids for {} rows\", slot_to_id.len(), inner.len()),\n            ));\n        }\n        let mut sorted = slot_to_id.clone();\n        sorted.sort_unstable();\n        if sorted.windows(2).any(|w| w[0] == w[1]) {\n            return Err(std::io::Error::new(\n                std::io::ErrorKind::InvalidData,\n                \"duplicate ids\",\n            ));\n        }\n        Ok(Self {\n            inner,\n            slot_to_id,\n            id_to_slot: std::sync::OnceLock::new(),\n            sorted_ids: std::sync::Mutex::new(sorted),\n            deferred_added: std::sync::Mutex::new(Default::default()),","sourceCodeStart":886,"sourceCodeEnd":922,"githubUrl":"https://github.com/RyanCodrai/turbovec/blob/ccab9f325e6ce2a270a87daf01ae4e443bcf2d49/turbovec/src/id_map.rs#L886-L922","documentation":"IdMap::from_index_and_ids requires the external-id vector to have exactly one id per row of the inner TurboQuantIndex. A length mismatch means the id metadata and the index rows disagree, so an InvalidData io::Error with the counts is returned instead of building a misaligned map.","triggerScenarios":"Constructing an IdMap (or wrapping API) with slot_to_id.len() != inner.len() — e.g. ids truncated, duplicated rows filtered from the index without updating ids, or loading an ids file from a different index build.","commonSituations":"Rebuilding an index with remove/rebuild and reusing a stale id vector; loading mismatched artifacts (index from one checkpoint, ids from another); off-by-one in a serialization step that dropped ids.","solutions":["Regenerate the id vector so it has exactly one entry per index row in the same order.","Ensure the index and ids come from the same build/checkpoint — rebuild both together.","If ids were filtered, apply the same filtering to the index (or vice versa) before calling from_index_and_ids."],"exampleFix":"// before\nlet map = IdMap::from_index_and_ids(index, stale_ids)?; // 1000 ids for 900 rows\n// after\nassert_eq!(stale_ids.len(), index.len(), \"ids/index length mismatch\");\nlet map = IdMap::from_index_and_ids(index, stale_ids)?;","handlingStrategy":"validation","validationCode":"if ids.len() != index.len() {\n    return Err(format!(\"{} ids for {} rows\", ids.len(), index.len()));\n}","typeGuard":null,"tryCatchPattern":"let map = IdMap::from_index_and_ids(index, ids)\n    .map_err(|e| { log::error!(\"id map build failed: {e}\"); BuildError::IdMismatch })?;","preventionTips":["Always build ids and index in the same pass; never reuse a stale id vector.","Keep index+ids artifacts versioned together (same checkpoint).","Assert length equality after every remove/filter operation."],"tags":["rust","id-map","io-error","length-mismatch","data-integrity"],"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"}