Hmbown/CodeWhale · error

fleet authority fingerprint `{expected}` is not a form this

Error message

fleet authority fingerprint `{expected}` is not a form this build understands; refusing the spawn rather than launching an unverified child

What it means

`verify_fleet_authority_input` parses the expected Fleet authority fingerprint by splitting on ';' into key=value fields; it must start with "v1;" and yield at least 8 fields. Anything else — a stale format from another build, a truncated string, a hand-built fingerprint — is an unparseable receipt and the spawn is refused rather than launching an unverified child (fail closed).

Source

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

/// The fingerprint is produced by `ChildAuthority::fingerprint` and names every
/// field of the envelope. Only four of them survive into the spawn input as
/// distinct keys — `write_authority`, `max_depth`, `allowed_tools`,
/// `disallowed_tools` — and those are exactly the four this function can and
/// does verify. The remaining fields (`tools`, `network`, `shell`, `posture`)
/// are *derivations* the Fleet used to compute those four, so a divergence in
/// any of them shows up in one of the four; verifying the wire form is
/// therefore the stronger check, not the weaker one, because it is the value
/// the child is actually constructed from.
///
/// Fails closed in every ambiguous case: an unparseable fingerprint is a
/// refusal, not a pass.
fn verify_fleet_authority_input(expected: &str, input: &Value) -> Result<()> {
    let fields: std::collections::HashMap<&str, &str> = expected
        .split(';')
        .filter_map(|part| part.split_once('='))
        .collect();
    if !expected.starts_with("v1;") || fields.len() < 8 {
        return Err(anyhow!(
            "fleet authority fingerprint `{expected}` is not a form this build understands; \
             refusing the spawn rather than launching an unverified child"
        ));
    }

    let listed = |key: &str| -> String {
        let mut values: Vec<String> = input
            .get(key)
            .and_then(Value::as_array)
            .map(|items| {
                items
                    .iter()
                    .filter_map(Value::as_str)
                    .map(str::to_string)
                    .collect()
            })
            .unwrap_or_default();
        values.sort();

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Regenerate the workflow/task receipt with the current build so the fingerprint is re-minted in v1 format.
  2. Check the fingerprint string starts with "v1;" and contains at least 8 key=value segments separated by ';'.
  3. Align the receipt-minting component and the verifying build to the same version; don't mix them.
  4. If you construct fingerprints programmatically, call the authority's fingerprint() method — never build the string by hand.

Example fix

// before: hand-built fingerprint
let fp = format!("write={};depth={}", w, d); // not v1; ... -> Err 1217

// after: use the authority's own minting
let fp = authority.fingerprint(); // "v1;write=...;depth=...;allow=...;deny=..." (8+ fields)
Defensive patterns

Strategy: validation

Validate before calling

fn fingerprint_is_parseable(expected: &str) -> bool {
    let fields: Vec<_> = expected.split(';').filter_map(|p| p.split_once('=')).collect();
    expected.starts_with("v1;") && fields.len() >= 8
}
// before spawn: if !fingerprint_is_parseable(fp) { re-mint the receipt }

Type guard

fn is_v1_fingerprint(expected: &str) -> bool {
    fingerprint_is_parseable(expected)
}

Try / catch

match verify_fleet_authority_input(expected, &input) {
    Err(e) if e.to_string().contains("not a form this build understands") => {
        // stale/malformed receipt: do NOT strip the fingerprint; re-mint it with the current build
    }
    r => r?,
}

Prevention

When it happens

Trigger: spawn_workflow_task with identity.fleet_authority_fingerprint that doesn't start with "v1;" or has fewer than 8 segments: receipts persisted by an older/newer version and replayed, a fingerprint truncated in storage or transit, or one assembled by string concatenation instead of the authority's fingerprint() method.

Common situations: Version skew between the component minting receipts and the one verifying; reusing persisted receipts after an upgrade; typo'd fingerprint configuration; hand-rolled fingerprint construction in extensions.

Related errors


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