Skip to content

fix: prevent panic in uniqueItems validation for unhashable types (#1042)#1045

Open
ArdyJunata wants to merge 1 commit into
danielgtaylor:mainfrom
ArdyJunata:fix/uniqueitems-panic-unhashable-type
Open

fix: prevent panic in uniqueItems validation for unhashable types (#1042)#1045
ArdyJunata wants to merge 1 commit into
danielgtaylor:mainfrom
ArdyJunata:fix/uniqueitems-panic-unhashable-type

Conversation

@ArdyJunata

Copy link
Copy Markdown

Summary

Fixes #1042

Problem

The uniqueItems check in handleArray used map[any]struct{} as a hash set. When array items contain non-hashable types such as map[string]interface{} — produced by malformed JSON like [{}] for a []string field — inserting into the map panics:

http: panic serving [::1]:59220: hash of unhashable type: map[string]interface {}

This caused the server to return no response at all instead of a 422 Unprocessable Entity. The panic kills the goroutine serving the request.

Reproduction:

curl -X POST -H 'Content-Type: application/json' \
  -d '{"arrayOfStrings": [{}]}' \
  http://localhost:8888/demo
# Server logs: panic serving ...: hash of unhashable type: map[string]interface {}

Fix

Introduce a uniqueItemsContains helper that:

  1. Fast path: attempts an O(1) map[any] lookup (works for all hashable types — strings, ints, bools, etc.)
  2. Slow path: a deferred recover() catches the panic for unhashable types and falls back to an O(n) reflect.DeepEqual linear scan

This means:

  • ✅ Normal arrays of hashable items → same O(n) performance as before
  • ✅ Arrays with maps/slices → graceful O(n²) fallback, no panic
  • ✅ Duplicate unhashable objects → still detected correctly
  • ✅ Malformed [{}] for []string → proper 422 expected string error

Tests

Three regression tests added to validate_test.go:

Test Verifies
uniqueItems with unhashable object element must not panic [{}] for []string returns 422, not a panic
uniqueItems detects duplicate unhashable objects [{"a":1},{"a":1}] is still detected as non-unique
uniqueItems with mixed hashable and unhashable elements ["ok", {"k":"v"}] does not panic

All existing tests continue to pass.

Fixes danielgtaylor#1042

The uniqueItems check in handleArray used map[any]struct{} as a hash
set. When array items contain non-hashable types such as
map[string]interface{} (produced by malformed JSON like [{"k":"v"}]
for a []string field), inserting into the map panics with:

  http: panic serving ...: hash of unhashable type: map[string]interface {}

This caused the server to return no response at all — not even a 500.

Fix: introduce a uniqueItemsContains helper that attempts the O(1) map
lookup on the fast path. A deferred recover() catches the panic for
unhashable types and falls back to an O(n) reflect.DeepEqual linear
scan, which:
  - Never panics regardless of element type
  - Still detects duplicate unhashable values correctly
  - Has no impact on the common case (hashable types hit the fast path)

Malformed input like [{"k":"v"}] for a []string field now correctly
returns a 422 'expected string' validation error instead of crashing.

Regression tests added in validate_test.go:
  - uniqueItems with unhashable object element must not panic
  - uniqueItems detects duplicate unhashable objects
  - uniqueItems with mixed hashable and unhashable elements must not panic
@codecov

codecov Bot commented Jun 12, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.16%. Comparing base (2b69054) to head (a093467).
⚠️ Report is 5 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1045      +/-   ##
==========================================
+ Coverage   93.14%   93.16%   +0.01%     
==========================================
  Files          23       23              
  Lines        4901     4913      +12     
==========================================
+ Hits         4565     4577      +12     
  Misses        272      272              
  Partials       64       64              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Validation of uniqueItems causes panic when input is not the expected type

1 participant