zeroclaw-labs/zeroclaw · error

invalid WeCom padding length

Error message

invalid WeCom padding length

What it means

strip_wecom_padding requires the final byte of the decrypted payload to be a pad length in 1..=32 that does not exceed the payload length. A value of 0, over 32, or larger than the input means the plaintext is corrupt — with a correct AES key WeCom's padding is always valid, so this almost always indicates a wrong key or truncated ciphertext.

Source

Thrown at crates/zeroclaw-channels/src/wecom_ws.rs:1870

            .remove(message_id)
            .unwrap_or_default();
        if !req_id.is_empty() {
            self.ws_send_respond_msg(&req_id, message_id, "", true)
                .await?;
        }
        Ok(())
    }
}

// ── Helper functions ─────────────────────────────────────────────────

fn strip_wecom_padding(input: &[u8]) -> Result<&[u8]> {
    let Some(last) = input.last() else {
        anyhow::bail!("invalid WeCom padding: empty payload");
    };
    let pad_len = *last as usize;
    if pad_len == 0 || pad_len > 32 || pad_len > input.len() {
        anyhow::bail!("invalid WeCom padding length");
    }
    Ok(&input[..input.len() - pad_len])
}

fn is_wecom_data_version_conflict_error(err: &anyhow::Error) -> bool {
    let msg = err.to_string();
    msg.contains("errcode=6000") || msg.contains("data version conflict")
}

fn parse_inbound_payload(payload: Value) -> Result<ParsedInbound> {
    let msg_type = payload
        .get("msgtype")
        .and_then(Value::as_str)
        .unwrap_or("")
        .to_string();
    if msg_type.is_empty() {
        anyhow::bail!("missing msgtype");
    }

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Re-enter the aes_key for the exact WeCom app — the dominant cause; confirm it decodes to 32 bytes
  2. Confirm the full ciphertext arrived (compare logged lengths; check for frame truncation)
  3. If only some messages fail, capture the failing payload and test decryption offline with the configured key
  4. After fixing credentials, restart the channel and verify with a fresh message
Defensive patterns

Strategy: try-catch

Try / catch

Catch the 'invalid WeCom padding length' bail per message and skip it deterministically; a failure rate near 100% means the aes_key is wrong — halt the channel, rotate credentials, and re-verify with a known-good test message.

Prevention

When it happens

Trigger: Decrypting with a mismatched or truncated aes_key (the code uses only the first 32 decoded bytes); ciphertext truncated in transit; a payload that is not WeCom-encrypted data reaching the decrypt path.

Common situations: EncodingAESKey copied from another app/environment; a key with trailing characters that shifts which 32 bytes are used; proxies truncating large frames; version skew changing the encryption envelope.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/7d4aec38828b5d9b. Report an issue: GitHub.