Hmbown/CodeWhale · error

invalid Runtime Chat fingerprint

Error message

invalid Runtime Chat fingerprint

What it means

`validate_fingerprint` requires a Runtime Chat fingerprint to be exactly 64 ASCII hex characters (a SHA-256 hex digest). Anything shorter, longer, or non-hex is rejected, because fingerprints are compared as digests for integrity.

Solutions

  1. Provide the lowercase hex-encoded SHA-256 digest (exactly 64 hex chars, no `0x` prefix).
  2. Recompute the fingerprint with the same hashing the relay uses (`Sha256::digest` + hex encoding).
  3. Strip whitespace and prefixes before validating.

Example fix

// before
let fp = format!("0x{}", hex_digest(Sha256::digest(value)));
relay.validate_fingerprint(&fp)?;
// after
let fp = hex_digest(Sha256::digest(value.as_bytes()));
relay.validate_fingerprint(&fp)?;
Defensive patterns

Strategy: validation

Validate before calling

fn is_sha256_hex(s: &str) -> bool { s.len() == 64 && s.bytes().all(|b| b.is_ascii_hexdigit()) }
if !is_sha256_hex(&fingerprint) { return Err("fingerprint must be 64 hex chars".into()); }

Type guard

fn sha256_hex(s: &str) -> Option<&str> { (s.len() == 64 && s.bytes().all(|b| b.is_ascii_hexdigit())).then_some(s) }

Try / catch

match relay.validate_fingerprint(&fp) { Err(_) => { let fp = hex_digest(Sha256::digest(value.as_bytes())); retry_with(fp) }, Ok(_) => proceed() }

Prevention

When it happens

Trigger: Passing a fingerprint that is not a 64-character hex string — e.g. a truncated hash, a base64 digest, or a value with `0x` prefix.

Common situations: Encoding the fingerprint differently than the producer (base64 vs hex); copying a hash with a prefix or whitespace; using a weaker hash like MD5 (32 hex chars).

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/5fa88f0b14995182. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/runtime_chat_relay.rs:1762

}

fn validate_route_id(value: &str, label: &str) -> Result<()> {
    if !crate::runtime_api::runtime_chat_route_id_is_safe(value) {
        bail!("invalid Runtime Chat {label}");
    }
    Ok(())
}

fn validate_model_id(value: &str) -> Result<()> {
    if !crate::runtime_api::runtime_chat_model_id_is_safe(value) {
        bail!("invalid Runtime Chat model id");
    }
    Ok(())
}

fn validate_fingerprint(value: &str) -> Result<()> {
    if value.len() != 64 || !value.bytes().all(|byte| byte.is_ascii_hexdigit()) {
        bail!("invalid Runtime Chat fingerprint");
    }
    Ok(())
}

fn fingerprint(value: &str) -> String {
    hex_digest(Sha256::digest(value.as_bytes()))
}

fn runtime_chat_request_fingerprint(command: &RuntimeChatPrompt) -> Result<String, String> {
    serde_json::to_value(command)
        .map(|value| canonical_json_value(&value))
        .and_then(|value| serde_json::to_vec(&value))
        .map(|bytes| hex_digest(Sha256::digest(bytes)))
        .map_err(|_| "Runtime Chat could not fingerprint its validated request.".to_string())
}

fn public_validation_error(_error: anyhow::Error) -> String {
    "The Runtime Chat command contains an invalid opaque identity.".to_string()

View on GitHub (pinned to 73e0f67d83)