go-playground/validator: 任意ポインタ項目に値制約タグを付けるなら omitempty 必須
go-playground/validator(validator/v10)で、未送信を許す任意フィールドをポインタ型(*string 等)にし、そこに max / min / len などの値制約タグだけを付けると、値が nil(未送信)でも制約が評価されてバリデーションに失敗する。validator はデフォルトでは nil ポインタを「検証スキップ」扱いにしないため、required も omitempty も無いポインタ項目は「未設定なら常にエラー」という直感に反する挙動になる。
ルール: 任意ポインタ項目に値制約タグを付けるときは必ず omitempty を併記する(例: validate:"omitempty,max=255")。omitempty があれば nil/ゼロ値のときは後続タグの評価がスキップされ、値があるときだけ制約が効く。
顕在化しやすいシナリオ: フォームが空文字 "" を送る経路では nil にならないので表面化せず、別の経路(既存値を読み直して再送する更新処理など)で当該キーが欠落/null になった瞬間に初めて 422 等で失敗する。つまり「特定の更新経路でだけ失敗する」症状になりやすく原因が見えにくい。
設計上の弱点: この種の validator は nil 緩和の共通機構(RegisterCustomTypeFunc 等)を入れていない限り、「任意ポインタ + 値制約 → omitempty 必須」という暗黙ルールに依存する。付け忘れが即バグになるため、レビュー観点・lint・テストで担保する価値がある。
検証方法: 該当フィールドを nil にしたリクエスト(または構造体)を 1 ケース用意し、バリデーションが通ることをユニットテストで固定する。値制約の上限超過で失敗する異常系と、nil で通過する正常系の両方を置くと回帰を防げる。
適用範囲: go 以外でも「ポインタ/Optional 型 + 値制約バリデーション」を持つ仕組み全般で、未設定値に制約を評価させない指定(omitempty 相当)の有無を確認するという形で転用できる。