| name | serde-code-review |
| description | Reviews serde serialization code for derive patterns, enum representations, custom implementations, and common serialization bugs. Use when reviewing Rust code that uses serde, serde_json, toml, or any serde-based serialization format. Covers attribute macros, field renaming, and format-specific pitfalls. |
Serde Code Review
Review Workflow
- Check Cargo.toml — Note serde features (
derive, rc), format crates (serde_json, toml, bincode, etc.), and Rust edition (2024 has breaking changes affecting serde code)
- Check derive usage — Verify
Serialize and Deserialize are derived appropriately
- Check enum representations — Enum tagging affects wire format compatibility and readability
- Check field attributes — Renaming, defaults, skipping affect API contracts
- Check edition 2024 compatibility — Reserved
gen keyword, RPIT lifetime capture changes, never_type_fallback
- Verify round-trip correctness — Serialized data must deserialize back to the same value
Output Format
Report findings as:
[FILE:LINE] ISSUE_TITLE
Severity: Critical | Major | Minor | Informational
Description of the issue and why it matters.
Quick Reference
Review Checklist
Derive Usage
Enum Representation
Field Configuration
Database Integration (sqlx)
Edition 2024 Compatibility
Correctness
Severity Calibration
Critical
- Enum representation mismatch between serializer and deserializer (data loss)
- Missing
#[serde(rename)] causing API-breaking field name changes
#[serde(flatten)] causing silent key collisions
- Lossy numeric conversions (
f64 precision loss for monetary values)
Major
- Inconsistent
rename_all across related types (confusing API)
- Missing
skip_serializing_if causing null/empty noise in output
deny_unknown_fields on types consumed by evolving APIs (breaks forward compatibility)
- Missing round-trip tests for complex enum representations
- Field or variant named
gen without r#gen escape (edition 2024 compile failure)
Minor
- Unnecessary
#[serde(default)] on required fields
- Using string representation for enums when numeric would be more efficient
- Verbose custom implementations where derive + attributes suffice
- Using
#[allow(unused)] instead of #[expect(unused)] for serde-only fields (prefer self-cleaning lint suppression)
Informational
- Suggestions to switch enum representation for cleaner wire format
- Suggestions to add
#[non_exhaustive] alongside serde for forward compatibility
Valid Patterns (Do NOT Flag)
- Externally tagged enums — serde's default, valid for many use cases
#[serde(untagged)] enums — Valid when discriminated by structure, not by tag
serde_json::Value for dynamic data — Appropriate for truly schema-less fields
#[serde(skip)] on computed fields — Correct for derived/cached values
#[serde(with = "...")] for custom formats — Standard for dates, UUIDs, etc.
r#gen with #[serde(rename = "gen")] — Correct edition 2024 workaround for gen fields in wire formats
+ use<'a> on custom serializer return types — Precise RPIT lifetime capture (edition 2024)
Before Submitting Findings
Load and follow beagle-rust:review-verification-protocol before reporting any issue.