heimdall-serde-pitfallslisted
Install: claude install-skill po4yka/heimdall
# Heimdall Serde Pitfalls
## Purpose
Guide review and authoring of `serde` serialization/deserialization code in heimdall. Apply every rule to every `#[derive(Serialize, Deserialize)]` and every serde attribute in a diff. Heimdall uses serde heavily in `src/models.rs`, `src/config.rs`, `src/server/` API types, and webhook payloads.
## `#[serde(untagged)]` swallows all variant errors
**Severity: WARNING**
When deserializing an `#[serde(untagged)]` enum, serde tries each variant in declaration order and discards every variant's specific error. On total failure, it reports only: `"data did not match any variant of untagged enum Foo"`. You lose the specific field name, type mismatch, or missing key that caused each failure.
```rust
#[derive(Deserialize)]
#[serde(untagged)]
enum WebhookPayload {
Anthropic(AnthropicEvent),
OpenAI(OpenAIEvent),
Gemini(GeminiEvent),
}
// On failure: "data did not match any variant" -- completely opaque in prod logs
```
Hazard: this makes debugging silent rejections in production webhook handlers require log enhancement or manual reproduction. The error is often discovered only after hours of investigation under production load.
Mitigations (in order of preference):
1. Use `#[serde(tag = "source")]` instead if the payload contains a type discriminant field.
2. Use `#[serde(try_from = "serde_json::Value")]` and implement `TryFrom` with explicit variant matching that returns typed errors.
3. Add a `#[serde(other)]` fallback variant t