{"record":{"id":"5ce84429bee25927","repo":"Hmbown/CodeWhale","slug":"invalid-runtime-chat-virtual-thread-id","errorCode":null,"errorMessage":"invalid Runtime Chat virtual thread id","messagePattern":"invalid Runtime Chat virtual thread id","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/runtime_chat_relay.rs","lineNumber":1717,"sourceCode":"    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\n        || !value.starts_with(\"local_turn_\")\n        || !value[11..]\n            .bytes()\n            .all(|byte| byte.is_ascii_digit() || matches!(byte, b'a'..=b'f'))\n    {\n        bail!(\"invalid Runtime Chat virtual turn id\");\n    }\n    Ok(())\n}\n\nfn validate_native_record_id(value: &str, label: &str) -> Result<()> {\n    if value.len() < 5","sourceCodeStart":1699,"sourceCodeEnd":1735,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/runtime_chat_relay.rs#L1699-L1735","documentation":"validate_virtual_thread_id requires virtual thread ids to be exactly 37 bytes, start with \"local_thread_\", and have a suffix of only ASCII digits and lowercase hex letters (a-f). These ids are locally generated; any other shape means the id was not produced by the local generator and is rejected.","triggerScenarios":"Calling validate_virtual_thread_id (directly or via RelayState::validate over bindings) with an id that is not 37 chars, lacks the \"local_thread_\" prefix, or whose 24-char suffix contains uppercase hex, 'g'-'z', punctuation, or spaces.","commonSituations":"Constructing a virtual thread id by hand in tests or tooling with the wrong length or prefix; passing a server- or provider-side thread id (e.g. a UUID with dashes or uppercase) where a local id is required; truncation of a valid id.","solutions":["Regenerate the id with the local virtual-thread-id generator instead of hand-building one","Fix the prefix to \"local_thread_\" and pad the suffix to exactly 24 hex/digit chars","Downcase hex digits and remove dashes/punctuation from the suffix","Verify length: 13 (prefix) + 24 (suffix) = 37 characters"],"exampleFix":"// before\nlet id = \"local_thread_ABC-123\"; // wrong length, uppercase, dashes\n// after\nlet id = \"local_thread_0123456789abcdef01234567\"; // 13 + 24 = 37 chars","handlingStrategy":"validation","validationCode":"fn looks_like_virtual_thread_id(value: &str) -> bool {\n    value.len() == 37\n        && value.starts_with(\"local_thread_\")\n        && value[13..].bytes().all(|b| b.is_ascii_digit() || matches!(b, b'a'..=b'f'))\n}","typeGuard":"fn as_virtual_thread_id(value: &str) -> Option<&str> {\n    looks_like_virtual_thread_id(value).then_some(value)\n}","tryCatchPattern":"if !looks_like_virtual_thread_id(&thread_id) {\n    eprintln!(\"regenerating virtual thread id (got {thread_id:?})\");\n    let thread_id = generate_virtual_thread_id();\n}","preventionTips":["Only create virtual thread ids with the local generator; never accept external ids in this field","Keep the 13+24=37 length invariant in a constructor function","Keep hex lowercase; strip dashes if converting from UUID-like sources"],"tags":["validation","identifier","format"],"backgroundTag":"invalid-identifier-format","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"}