{"record":{"id":"ad34c7b38535b0ec","repo":"vectordotdev/vector","slug":"entry-must-exist","errorCode":null,"errorMessage":"entry must exist","messagePattern":"entry must exist","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/codecs/src/decoding/framing/chunked_gelf.rs","lineNumber":521,"sourceCode":"                let owns_message = pending\n                    .messages\n                    .get(&message_id)\n                    .is_some_and(|message| message.timeout_task.id() == timeout_task_id);\n                if owns_message && pending.remove(message_id).is_some() {\n                    warn!(\n                        message_id = message_id,\n                        timeout_secs = timeout.as_secs_f64(),\n                        \"Message was not fully received within the timeout window. Discarding it.\"\n                    );\n                }\n            });\n            pending.messages.insert(\n                message_id,\n                Box::new(MessageState::new(total_chunks, timeout_handle)),\n            );\n        }\n\n        let message_state = pending.messages.get(&message_id).expect(\"entry must exist\");\n\n        ensure!(\n            message_state.total_chunks == total_chunks,\n            TotalChunksMismatchSnafu {\n                message_id,\n                sequence_number,\n                original_total_chunks: message_state.total_chunks,\n                received_total_chunks: total_chunks\n            }\n        );\n\n        if message_state.is_chunk_present(sequence_number) {\n            debug!(\n                message_id = message_id,\n                sequence_number = sequence_number,\n                \"Received a duplicate chunk. Ignoring it.\"\n            );\n            return Ok(None);","sourceCodeStart":503,"sourceCodeEnd":539,"githubUrl":"https://github.com/vectordotdev/vector/blob/bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013/lib/codecs/src/decoding/framing/chunked_gelf.rs#L503-L539","documentation":"After possibly inserting a new `MessageState`, `decode_chunk` re-reads the message from `pending.messages` and asserts with `expect(\"entry must exist\")` that it is present. This is an internal invariant: the code either just inserted the entry or verified it exists earlier (the `is_new_message` check), both under the same held lock, so absence means a logic bug.","triggerScenarios":"Calling `decode_chunk` (via `decode_message`) when the map lookup after insert/check returns None — theoretically impossible while the lock is held; would require a bug in the insertion/check logic or lock-escaping mutation.","commonSituations":"Effectively only hit by developers modifying the decoder (e.g. moving the insert, changing the ID type, or dropping the lock mid-function) and breaking the invariant.","solutions":["Audit recent changes to `decode_chunk`: ensure the insert (or the contains_key check) executes before this lookup under the same lock guard","Verify `message_id` is not mutated or cloned inconsistently between check and lookup","Replace the `expect` with proper error propagation if the invariant cannot be guaranteed"],"exampleFix":"// before\nlet message_state = pending.messages.get(&message_id).expect(\"entry must exist\");\n// after\nlet message_state = pending.messages.get(&message_id).ok_or_else(||\n    ChunkedGelfDecoderError::InternalState { message_id: message_id.clone() })?;","handlingStrategy":"validation","validationCode":"// Rust: verify message presence before re-lookup (mirrors decoder invariant)\nassert!(pending.messages.contains_key(&message_id), \"message state missing for id {message_id:?}\");","typeGuard":"fn message_state_exists(pending: &PendingMessages, id: &MessageId) -> bool {\n    pending.messages.contains_key(id)\n}","tryCatchPattern":"let message_state = pending.messages.get(&message_id)\n    .ok_or_else(|| ChunkedGelfDecoderError::InternalState { message_id: message_id.clone() })?;","preventionTips":["Keep insert/check/lookup within one lock-held region in decode_chunk","Write unit tests covering new-message, duplicate-chunk, and completion paths","Avoid refactors that drop the mutex guard between the check and the lookup"],"tags":["rust","gelf","chunked","invariant","expect"],"backgroundTag":"internal-invariant-violation","analyzedSha":"bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013","analyzedAt":"2026-09-16T02:53:35.741Z","contentChangedAt":"2026-09-16T02:53:35.741Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}