{"record":{"id":"73b1d521468ea6eb","repo":"huggingface/candle","slug":"one-hot-index-out-of-bounds-idx-len","errorCode":null,"errorMessage":"one_hot: index out of bounds {idx}, len {}","messagePattern":"one_hot: index out of bounds (.+?), len (.+?)","errorType":"exception","errorClass":"candle::Error","httpStatus":null,"severity":"error","filePath":"candle-nn/src/encoding.rs","lineNumber":146,"sourceCode":"    on_value: D,\n) -> Result<()> {\n    let value = value.into();\n    // Skip for an entire row of off_values\n    if value == -1 {\n        return Ok(());\n    }\n    if value < -1 {\n        bail!(\n            \"one_hot: invalid negative index value {value}, expected a positive index value or -1\"\n        );\n    }\n    let value = value as usize;\n    if value >= depth {\n        bail!(\"one_hot: index value {value} exceeds depth {depth}\")\n    }\n    let idx = offset + value;\n    if idx >= v.len() {\n        bail!(\"one_hot: index out of bounds {idx}, len {}\", v.len());\n    }\n    v[idx] = on_value;\n    Ok(())\n}\n","sourceCodeStart":128,"sourceCodeEnd":151,"githubUrl":"https://github.com/huggingface/candle/blob/d5fee525bfde3273eb7c9b75fd2bc4937be867ca/candle-nn/src/encoding.rs#L128-L151","documentation":"After the depth check passes, set_at_index computes `idx = offset + value` into the flat output vector of length batch*depth (plus any offset base). If the computed flat position still falls outside the vector, this bail fires — it indicates the `offset` argument is inconsistent with the vector length rather than a bad class value.","triggerScenarios":"Calling one_hot where the internal buffer v does not have room for offset+value: i.e. v.len() <= offset + value. Practically this arises when the output buffer was allocated for a smaller depth/batch than the offsets/indexes assume.","commonSituations":"Library-internal buffer sizing bug or a custom call to set_at_index with mismatched offset and buffer length; batch-size mismatch between the allocated one-hot buffer and the number of labels; partially filled/stale buffer reused across calls.","solutions":["Ensure the destination vector length equals batch_size * depth and each offset is batch_index * depth before calling set_at_index.","Re-allocate the one-hot buffer from the actual tensor batch size instead of reusing a cached buffer.","Update/upgrade candle-nn — if this fires from the public one_hot API itself, it is a sizing bug; check for a fixed release or file an issue with the reproducing shapes.","As a workaround, build the one-hot tensor manually via zeros + scatter_add or Tensor::onehot-equivalent ops."],"exampleFix":"// before: buffer allocated for old batch\nlet mut v = vec![off_value; old_bsz * depth];\n// after\nlet bsz = labels.elem_count();\nlet mut v = vec![off_value; bsz * depth];\nfor (i, &val) in labels.to_vec1::<u32>()?.iter().enumerate() {\n    set_at_index(&mut v, i * depth, val as usize, depth, on_value)?;\n}","handlingStrategy":"validation","validationCode":"let bsz = labels.elem_count();\nassert_eq!(buffer.len(), bsz * depth, \"one_hot buffer sized {} != {}\", buffer.len(), bsz * depth);","typeGuard":null,"tryCatchPattern":"let result = std::panic::catch_unwind(|| one_hot(&labels, depth));\nmatch result {\n    Ok(Ok(t)) => t,\n    _ => {\n        let v = vec![0f32; labels.elem_count() * depth]; // re-allocate correctly sized buffer\n        one_hot(&labels, depth)?\n    }\n}","preventionTips":["Always allocate one-hot buffers as batch_size * depth from the live tensor, never from cached sizes","Rebuild buffers when batch size changes (last batch may be smaller)","Prefer calling the public one_hot API over hand-managing offsets into flat buffers","Pin your candle-nn version and test one_hot after upgrades"],"tags":["tensor","encoding","bounds","rust"],"backgroundTag":"index-out-of-range","analyzedSha":"d5fee525bfde3273eb7c9b75fd2bc4937be867ca","analyzedAt":"2026-09-02T00:15:47.023Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}