{"record":{"id":"e7d24f8ebb67321e","repo":"Hmbown/CodeWhale","slug":"runtime-chat-operation-key-is-too-long","errorCode":null,"errorMessage":"Runtime Chat operation key is too long","messagePattern":"Runtime Chat operation key is too long","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/runtime_chat_relay.rs","lineNumber":1705,"sourceCode":"fn validate_relay_id(value: &str, label: &str) -> Result<()> {\n    if value.is_empty()\n        || value.len() > MAX_RELAY_ID_BYTES\n        || value.contains(\"..\")\n        || value.contains(\"://\")\n        || !value.bytes().all(|byte| {\n            byte.is_ascii_alphanumeric()\n                || matches!(byte, b'.' | b'_' | b':' | b'@' | b'/' | b'+' | b'~' | b'-')\n        })\n    {\n        bail!(\"invalid Runtime Chat {label}\");\n    }\n    Ok(())\n}\n\nfn validate_operation_key(value: &str) -> Result<()> {\n    validate_relay_id(value, \"operation key\")?;\n    if value.len() > MAX_OPERATION_KEY_BYTES {\n        bail!(\"Runtime Chat operation key is too long\");\n    }\n    Ok(())\n}\n\nfn validate_virtual_thread_id(value: &str) -> Result<()> {\n    if value.len() != 37\n        || !value.starts_with(\"local_thread_\")\n        || !value[13..]\n            .bytes()\n            .all(|byte| byte.is_ascii_digit() || matches!(byte, b'a'..=b'f'))\n    {\n        bail!(\"invalid Runtime Chat virtual thread id\");\n    }\n    Ok(())\n}\n\nfn validate_virtual_turn_id(value: &str) -> Result<()> {\n    if value.len() != 35","sourceCodeStart":1687,"sourceCodeEnd":1723,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/runtime_chat_relay.rs#L1687-L1723","documentation":"validate_operation_key first applies the general relay-id rules and then enforces a maximum length of MAX_OPERATION_KEY_BYTES. Operation keys that exceed this byte budget are rejected because keys are used as state-map keys and must stay bounded.","triggerScenarios":"Calling validate_operation_key with a string longer than MAX_OPERATION_KEY_BYTES (check the constant in crates/tui/src/runtime_chat_relay.rs) — typically very long generated operation ids or concatenated labels.","commonSituations":"Building operation keys by concatenating route + thread + turn ids without bounding them; a provider returning oversized operation identifiers; unbounded user input used as an operation key.","solutions":["Truncate or hash the operation key (e.g. SHA-256 hex) before validating","Shorten the components concatenated into the key (use shorter ids or drop redundant prefixes)","Check MAX_OPERATION_KEY_BYTES and assert key length at construction time","Stop using unbounded user input as an operation key"],"exampleFix":"// before\nlet key = format!(\"{route}/{thread}/{turn}/{fingerprint}\");\n// after\nlet key = sha256_hex(format!(\"{route}/{thread}/{turn}/{fingerprint}\"));","handlingStrategy":"validation","validationCode":"fn operation_key_fits(key: &str) -> bool { key.len() <= MAX_OPERATION_KEY_BYTES }\nfn bounded_key(parts: &[&str]) -> String {\n    let joined = parts.join(\":\");\n    if joined.len() > MAX_OPERATION_KEY_BYTES {\n        sha256_hex(&joined) // fixed-length fallback\n    } else { joined }\n}","typeGuard":"fn as_operation_key(value: &str) -> Option<&str> {\n    (value.len() <= MAX_OPERATION_KEY_BYTES).then_some(value)\n}","tryCatchPattern":"if let Err(e) = validate_operation_key(&key) {\n    if e.to_string().contains(\"too long\") {\n        let key = hash_key(&raw); // retry with a hashed, fixed-length key\n    }\n}","preventionTips":["Bound every component concatenated into an operation key","Hash unbounded inputs into fixed-length keys before use","Assert key length in unit tests for any new key-composition code"],"tags":["validation","length-limit","identifier"],"backgroundTag":"value-out-of-range","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}