Parse, Don't Validate (2019)

Overall reception & scope of the idea

  • Many commenters call the article one of their favorites and “seminal,” returning to it regularly.
  • Core takeaway: it is not “don’t validate,” but “validate once, at the boundary, and turn raw data into richer types so the rest of the code can assume invariants.”
  • Some note the title causes confusion, leading people to argue against positions the article doesn’t actually take.

Error handling vs “sane defaults”

  • Debate around patterns like TryParse with silent fallbacks to “sane defaults.”
  • Several argue this is dangerous: invalid input should fail loudly, not be silently replaced, or bugs become hard to trace.
  • Others counter that strict failure is sometimes user-hostile (e.g., malformed footnote, hotel room selection); partial success with warnings can be preferable, but must not be silent.
  • Crowdstrike’s outage is cited as an example of not planning for invalid configs at all.

Using types to make invalid states impossible

  • Strong support for modeling states in the type system: e.g., UncheckedEmailValidEmailVerifiedEmail, or User vs VerifiedUser.
  • This avoids boolean flags and re-checks, and lets the compiler enforce correct usage.
  • Disagreement on how far to go: some prefer only “valid” types; others find intermediate-state types essential, especially for multi-step workflows.
  • Non-empty lists and smart constructors are discussed as practical patterns.

Language-specific perspectives

  • Pattern seen as working well in F#, C#, Rust, TypeScript (with type predicates, Zod, effect/schema), and in FP languages with algebraic data types.
  • Go’s zero values and JSON handling make this style harder, forcing more validation between parse and use.
  • Haskell/OCaml list types and non-empty variants are dissected; historical choices are called “warts” but entrenched.
  • Clarifications around Void/void vs unit types to avoid confusion between “no value” and “never returns.”

Validation placement, duplication, and security

  • Advocates stress that once parsed into safe types, repeated checks (“shotgun parsing”) are a code smell and violate DRY.
  • Others argue re-checking can be justified as defense in depth but may reflect “anxiety-driven development.”
  • One concern: exposed APIs still need protection against malicious payloads and resource exhaustion; reply is that buggy parsers are just bugs, and centralizing parsing tends to improve, not reduce, robustness.