Hmbown/CodeWhale · error

sub-agent transcript record is missing its message

Error message

sub-agent transcript record is missing its message

What it means

A message record passed the kind and index checks but has no "message" field to deserialize. The loader clones that field into a Message value; a record without the payload cannot be turned into a message and the load aborts.

Source

Thrown at crates/tui/src/tools/subagent/mod.rs:7621

        if record.get("kind").and_then(Value::as_str) != Some("message") {
            return Err(anyhow!("unknown sub-agent transcript artifact record"));
        }
        let index = record
            .get("index")
            .and_then(Value::as_u64)
            .and_then(|value| usize::try_from(value).ok())
            .ok_or_else(|| anyhow!("sub-agent transcript message is missing its index"))?;
        if index != messages.len() {
            return Err(anyhow!(
                "sub-agent transcript message index {index} does not follow {}",
                messages.len()
            ));
        }
        let message = serde_json::from_value::<Message>(
            record
                .get("message")
                .cloned()
                .ok_or_else(|| anyhow!("sub-agent transcript record is missing its message"))?,
        )?;
        messages.push(message);
    }
    Ok(messages)
}

fn remove_subagent_transcript_artifact(state_root: &Path, agent_id: &str) -> Result<bool> {
    let state_root = normalize_subagent_workspace(state_root);
    let path = checked_subagent_transcript_artifact_path(&state_root, agent_id)?;
    reject_root_relative_symlinks(&state_root, &path)?;
    let metadata = match fs::symlink_metadata(&path) {
        Ok(metadata) => metadata,
        Err(err) if err.kind() == std::io::ErrorKind::NotFound => return Ok(false),
        Err(err) => return Err(err.into()),
    };
    if metadata.file_type().is_symlink() || !metadata.file_type().is_file() {
        return Err(anyhow!(
            "sub-agent transcript artifact is not a regular file: {}",

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Remove or complete the stub record so every message line embeds the full message object.
  2. Regenerate the artifact via re-run rather than editing partial lines by hand.
  3. If a writer bug produced it, fix that writer to emit the whole record atomically (one JSON line per record).
Defensive patterns

Strategy: try-catch

Validate before calling

for line in raw.lines().skip(1) {
    let v: serde_json::Value = serde_json::from_str(line)?;
    if v.get("message").is_none() { /* stub record without payload: complete or drop it */ }
}

Type guard

fn record_has_message(v: &serde_json::Value) -> bool {
    v.get("message").is_some()
}

Try / catch

match load_subagent_transcript_artifact(&state_root, agent_id) {
    Err(e) if e.to_string().contains("missing its message") => { /* remove stub record, renumber, or regenerate */ }
    r => r?,
}

Prevention

When it happens

Trigger: Records written with kind and index only (partial write, crash between field writes, or an external writer emitting a stub record).

Common situations: Interrupted writes leaving truncated JSON objects; hand-crafted records; a writer bug that serializes metadata without the message payload.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20). Data as JSON: /api/errors/2a1a2a4b6c42b334. Report an issue: GitHub.