{"record":{"id":"c0498d7ff9b2f202","repo":"Hmbown/CodeWhale","slug":"unknown-sub-agent-transcript-artifact-record","errorCode":null,"errorMessage":"unknown sub-agent transcript artifact record","messagePattern":"unknown sub-agent transcript artifact record","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/tools/subagent/mod.rs","lineNumber":7604,"sourceCode":"    let header_line = lines\n        .next()\n        .ok_or_else(|| anyhow!(\"sub-agent transcript artifact is empty\"))?;\n    let header: Value = serde_json::from_str(header_line)?;\n    if header.get(\"kind\").and_then(Value::as_str) != Some(\"subagent_transcript_header\")\n        || header.get(\"schema_version\").and_then(Value::as_u64)\n            != Some(u64::from(SUBAGENT_TRANSCRIPT_ARTIFACT_SCHEMA_VERSION))\n        || header.get(\"agent_id\").and_then(Value::as_str) != Some(agent_id)\n    {\n        return Err(anyhow!(\n            \"sub-agent transcript artifact header does not match agent {agent_id}\"\n        ));\n    }\n\n    let mut messages = Vec::new();\n    for line in lines.filter(|line| !line.trim().is_empty()) {\n        let record: Value = serde_json::from_str(line)?;\n        if record.get(\"kind\").and_then(Value::as_str) != Some(\"message\") {\n            return Err(anyhow!(\"unknown sub-agent transcript artifact record\"));\n        }\n        let index = record\n            .get(\"index\")\n            .and_then(Value::as_u64)\n            .and_then(|value| usize::try_from(value).ok())\n            .ok_or_else(|| anyhow!(\"sub-agent transcript message is missing its index\"))?;\n        if index != messages.len() {\n            return Err(anyhow!(\n                \"sub-agent transcript message index {index} does not follow {}\",\n                messages.len()\n            ));\n        }\n        let message = serde_json::from_value::<Message>(\n            record\n                .get(\"message\")\n                .cloned()\n                .ok_or_else(|| anyhow!(\"sub-agent transcript record is missing its message\"))?,\n        )?;","sourceCodeStart":7586,"sourceCodeEnd":7622,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/tools/subagent/mod.rs#L7586-L7622","documentation":"While parsing lines after the header, `load_subagent_transcript_artifact` found a line whose JSON \"kind\" field is not \"message\". Only message records are valid in a transcript artifact; any other record kind (or a stray JSON line from another writer) aborts the load.","triggerScenarios":"A JSONL line appended by a different producer (structured logs, tool output) into the artifact; mixed-format artifacts from a partial migration; hand-appended diagnostic records.","commonSituations":"State files shared with logging output; scripts that append to files under the state root; artifact formats changed between versions leaving old-style records in place.","solutions":["Inspect the artifact for the offending line (first line after the header whose kind != \"message\") and remove or fix it.","Ensure only the sub-agent persister writes transcript artifacts; move logs elsewhere.","Regenerate the artifact by re-running the sub-agent if manual repair is impractical."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Scan artifact lines for foreign records before loading:\nfor (i, line) in raw.lines().enumerate().skip(1) {\n    if let Ok(v) = serde_json::from_str::<serde_json::Value>(line) {\n        if v[\"kind\"].as_str() != Some(\"message\") { /* line {i} is foreign: fix or remove */ }\n    }\n}","typeGuard":"fn line_is_message_record(line: &str) -> bool {\n    serde_json::from_str::<serde_json::Value>(line)\n        .map(|v| v.get(\"kind\").and_then(|k| k.as_str()) == Some(\"message\"))\n        .unwrap_or(false)\n}","tryCatchPattern":"match load_subagent_transcript_artifact(&state_root, agent_id) {\n    Err(e) if e.to_string().contains(\"unknown sub-agent transcript artifact record\") => { /* locate + strip foreign line, retry once */ }\n    r => r?,\n}","preventionTips":["Only the sub-agent persister writes artifact files.","Keep logs and tool output out of the state root's artifact paths.","Validate artifacts with a dry parse after any manual maintenance."],"tags":["subagent","transcript","record-type","corruption","rust"],"backgroundTag":"unknown-record-type","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}