{"record":{"id":"c8c630cf097f1ca7","repo":"can1357/oh-my-pi","slug":"invalidarg-c8c630","errorCode":"InvalidArg","errorMessage":"contents changed during reranking","messagePattern":"contents changed during reranking","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"crates/pi-natives/src/vectors.rs","lineNumber":283,"sourceCode":"pub fn mmr_rerank_indices(\n\t#[napi(ts_arg_type = \"Array<string>\")] contents: Array,\n\tscores: Float64Array,\n\tlambda_param: f64,\n\ttop_k: u32,\n) -> Result<Uint32Array> {\n\tif scores.len() != contents.len() as usize {\n\t\treturn invalid(\"scores length must equal contents length\");\n\t}\n\tlet limit = top_k as usize;\n\tlet count = contents.len() as usize;\n\tif limit == 0 || count == 0 {\n\t\treturn Ok(Uint32Array::new(Vec::new()));\n\t}\n\tlet mut sets = Vec::with_capacity(count);\n\tfor index in 0..contents.len() {\n\t\tlet content = contents\n\t\t\t.get::<JsString>(index)?\n\t\t\t.ok_or_else(|| Error::new(Status::InvalidArg, \"contents changed during reranking\"))?;\n\t\tsets.push(word_set(&js::utf8(content)?));\n\t}\n\tlet mut selected: Vec<u32> = Vec::with_capacity(limit.min(count));\n\tselected.push(0);\n\tlet mut remaining: Vec<u32> = (1..count as u32).collect();\n\n\twhile !remaining.is_empty() && selected.len() < limit {\n\t\tlet mut best_idx = 0usize;\n\t\tlet mut best_score = f64::NEG_INFINITY;\n\t\tfor (idx, &candidate) in remaining.iter().enumerate() {\n\t\t\tlet mut max_similarity = 0.0f64;\n\t\t\tfor &picked in &selected {\n\t\t\t\tlet similarity = jaccard_sorted(&sets[candidate as usize], &sets[picked as usize]);\n\t\t\t\tif similarity > max_similarity {\n\t\t\t\t\tmax_similarity = similarity;\n\t\t\t\t}\n\t\t\t}\n\t\t\tlet relevance = scores[candidate as usize];","sourceCodeStart":265,"sourceCodeEnd":301,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/crates/pi-natives/src/vectors.rs#L265-L301","documentation":"mmr_rerank_indices takes a JS Array of strings plus parallel scores. During element extraction it reads each entry as a string; if an element is absent (not a string) at read time, it throws InvalidArg with this message. The name reflects the design assumption: contents was mutated between the length check and element access, or contains non-string entries.","triggerScenarios":"Calling native.mmrRerankIndices(contents, scores, lambda, topK) where contents contains null/undefined/non-string elements (including sparse array holes), or where contents is mutated concurrently while the synchronous call runs.","commonSituations":"Passing sparse arrays or arrays containing undefined holes; search/rerank pipelines that build the contents array incorrectly (e.g. forgetting to coalesce a missing document field); passing objects or numbers instead of strings.","solutions":["Ensure every element of contents is a non-null string before calling (filter/coalesce missing entries)","Ensure contents.length === scores.length and the array is not mutated during the call","Normalize entries: contents.map(c => typeof c === 'string' ? c : '') or filter with an index map to keep alignment","Catch the InvalidArg and fall back to a JS MMR implementation"],"exampleFix":"// before\nnative.mmrRerankIndices(contents, scores, 0.7, 10);\n// after\nconst clean = contents.map(c => (typeof c === 'string' ? c : ''));\nif (clean.length !== scores.length) throw new Error('contents/scores length mismatch');\nnative.mmrRerankIndices(clean, scores, 0.7, 10);","handlingStrategy":"validation","validationCode":"if (!Array.isArray(contents) || contents.some(c => typeof c !== 'string')) throw new TypeError('contents must be an array of strings');\nif (contents.length !== scores.length) throw new Error('contents and scores must have equal length');","typeGuard":"const isStringArray = (a) => Array.isArray(a) && a.every(x => typeof x === 'string');","tryCatchPattern":"try {\n  return native.mmrRerankIndices(contents, scores, lambda, topK);\n} catch (err) {\n  if (err?.code === 'InvalidArg' && String(err?.message).includes('contents changed during reranking')) {\n    return jsMmrRerank(contents, scores, lambda, topK);\n  } throw err;\n}","preventionTips":["Always normalize contents to a dense string array before calling","Keep contents immutable during the synchronous call","Keep contents and scores index-aligned"],"tags":["native","validation","mmr","reranking","array"],"backgroundTag":"array-element-type-mismatch","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}