{"record":{"id":"0dcb3cee71b8ed32","repo":"janhq/jan","slug":"failed-to-read-key-for-metadata-entry","errorCode":null,"errorMessage":"Failed to read key for metadata entry {}: {}","messagePattern":"Failed to read key for metadata entry (.+?): (.+?)","errorType":"validation","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"src-tauri/plugins/tauri-plugin-llamacpp/src/gguf/helpers.rs","lineNumber":133,"sourceCode":"                    format!(\"Error reading metadata entry {}: {}\", i, e),\n                ));\n            }\n        }\n    }\n\n    Ok(GgufMetadata {\n        version,\n        tensor_count,\n        metadata: metadata_map,\n    })\n}\n\nfn read_metadata_entry<R: Read + Seek + ReadBytesExt>(\n    reader: &mut R,\n    index: u64,\n) -> io::Result<(String, String)> {\n    let key = read_gguf_string(reader).map_err(|e| {\n        io::Error::new(\n            io::ErrorKind::InvalidData,\n            format!(\"Failed to read key for metadata entry {}: {}\", index, e),\n        )\n    })?;\n\n    let value_type_u32 = reader.read_u32::<LittleEndian>()?;\n    let value_type = GgufValueType::try_from(value_type_u32)?;\n    let value = read_gguf_value(reader, value_type)?;\n\n    Ok((key, value))\n}\n\nfn read_gguf_string<R: Read + ReadBytesExt>(reader: &mut R) -> io::Result<String> {\n    let len = reader.read_u64::<LittleEndian>()?;\n    if len > (1024 * 1024) {\n        return Err(io::Error::new(\n            io::ErrorKind::InvalidData,\n            format!(\"String length {} is unreasonably large\", len),","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/janhq/jan/blob/7205d770c1e097c3daf35a911176410e93bc5564/src-tauri/plugins/tauri-plugin-llamacpp/src/gguf/helpers.rs#L115-L151","documentation":"read_metadata_entry could not read the length-prefixed key string for metadata entry `index`. read_gguf_string's failure (oversized length > 1 MiB, truncated data, or invalid UTF-8) is re-tagged with the entry index for diagnosis.","triggerScenarios":"Calling read_gguf_metadata / find_gguf_tensors on a file where entry `index`'s u64 key-length prefix is garbage (points past EOF or exceeds 1 MiB) or the key bytes are truncated.","commonSituations":"Corrupted or partially downloaded GGUF files, desynchronized parsing after an earlier bad record, files produced by buggy converters writing wrong length prefixes.","solutions":["Re-download the model file and verify its checksum","Check the file with llama.cpp's gguf_dump to find where the KV section breaks","Verify the file size matches the publisher's expected size (truncation check)","If converting yourself, re-run the conversion with a current llama.cpp/gguf tool version"],"exampleFix":"// before\nlet meta = read_gguf_metadata(File::open(\"model.gguf\")?)?;\n// after\nlet bytes = std::fs::read(\"model.gguf\")?;\nif bytes.len() != EXPECTED_SIZE {\n    anyhow::bail!(\"download incomplete: {} of {} bytes\", bytes.len(), EXPECTED_SIZE);\n}\nlet meta = read_gguf_metadata(Cursor::new(bytes))?;","handlingStrategy":"validation","validationCode":"fn plausible_gguf_size(path: &std::path::Path, expected: u64) -> io::Result<bool> {\n    Ok(std::fs::metadata(path)?.len() == expected)\n}\n// truncated files produce garbage length prefixes","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Verify file size against the publisher's published size after download","Re-download rather than retry-parsing when this error appears","Run gguf_dump once on new model files before wiring them into the app"],"tags":["gguf","metadata","corrupt-file","binary-parsing"],"backgroundTag":"file-read-failed","analyzedSha":"7205d770c1e097c3daf35a911176410e93bc5564","analyzedAt":"2026-09-17T14:27:30.100Z","contentChangedAt":"2026-09-17T14:27:30.100Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}