{"record":{"id":"68be3b7db537271c","repo":"Hmbown/CodeWhale","slug":"operation-key-cannot-exceed-max-runtime-turn-operation-key","errorCode":null,"errorMessage":"operation_key cannot exceed {MAX_RUNTIME_TURN_OPERATION_KEY_BYTES} UTF-8 bytes","messagePattern":"operation_key cannot exceed (.+?) UTF-8 bytes","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/runtime_threads.rs","lineNumber":3502,"sourceCode":"}\n\n/// Lookup errors deliberately omit operation keys and persisted file paths.\n#[derive(Debug, thiserror::Error)]\npub(crate) enum RuntimeTurnOperationLookupError {\n    #[error(\"Invalid thread id or operation key\")]\n    InvalidRequest,\n    #[error(\"Turn operation acceptance is incomplete; retry lookup\")]\n    Incomplete,\n    #[error(\"Turn operation lookup unavailable\")]\n    Unavailable,\n}\n\nfn validate_runtime_turn_operation_key(value: &str) -> Result<()> {\n    if value.is_empty() {\n        bail!(\"operation_key cannot be empty\");\n    }\n    if value.len() > MAX_RUNTIME_TURN_OPERATION_KEY_BYTES {\n        bail!(\"operation_key cannot exceed {MAX_RUNTIME_TURN_OPERATION_KEY_BYTES} UTF-8 bytes\");\n    }\n    if value.trim() != value {\n        bail!(\"operation_key cannot contain leading or trailing whitespace\");\n    }\n    if value.chars().any(char::is_control) {\n        bail!(\"operation_key cannot contain control characters\");\n    }\n    Ok(())\n}\n\nfn validate_sha256_fingerprint(value: &str, label: &str) -> Result<()> {\n    if value.len() != 64 || !value.bytes().all(|byte| byte.is_ascii_hexdigit()) {\n        bail!(\"{label} must be a SHA-256 hex digest\");\n    }\n    Ok(())\n}\n\nfn runtime_turn_operation_key_fingerprint(","sourceCodeStart":3484,"sourceCodeEnd":3520,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/runtime_threads.rs#L3484-L3520","documentation":"validate_runtime_turn_operation_key rejects operation keys that are empty, over MAX_RUNTIME_TURN_OPERATION_KEY_BYTES UTF-8 bytes, have surrounding whitespace, or contain control chars. This check keeps runtime turn operation keys canonical so they can be used as stable identifiers and fingerprinted deterministically across processes.","triggerScenarios":"Calling any Runtime turn API that accepts an operation_key (e.g. runtime turn submission in crates/tui/src/runtime_threads.rs) with a string whose UTF-8 byte length exceeds MAX_RUNTIME_TURN_OPERATION_KEY_BYTES.","commonSituations":"Auto-generated keys that embed long tool names, thread IDs, or payloads; concatenating prefixes such that the key silently grows past the byte cap.","solutions":["Shorten the operation_key below the byte limit (derive it from a hash or fixed prefix instead of raw long data)","Check MAX_RUNTIME_TURN_OPERATION_KEY_BYTES and assert your key length in code before calling","Trim or normalize key generation to a bounded canonical format"],"exampleFix":"// before\nlet key = format!(\"turn:{thread_id}:{huge_payload_json}\");\n// after\nlet key = format!(\"turn:{}\", sha256_hex(huge_payload_json.as_bytes()));","handlingStrategy":"validation","validationCode":"fn ensure_operation_key(key: &str) -> Result<(), String> {\n    if key.is_empty() { return Err(\"empty\".into()); }\n    if key.len() > MAX_RUNTIME_TURN_OPERATION_KEY_BYTES { return Err(\"too long\".into()); }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Generate keys from fixed-width hashes, not raw payloads","Add a debug_assert on key byte length at construction","Never embed unbounded user data in operation keys"],"tags":["validation","runtime","rust"],"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-22T21:17:16.096Z"}