Skip to content

Fix NPE in JsonCodec.deserializeShape that suppresses deserialization errors#1203

Merged
adwsingh merged 1 commit into
smithy-lang:mainfrom
etspaceman:fix/json-deserializer-close-npe
May 22, 2026
Merged

Fix NPE in JsonCodec.deserializeShape that suppresses deserialization errors#1203
adwsingh merged 1 commit into
smithy-lang:mainfrom
etspaceman:fix/json-deserializer-close-npe

Conversation

@etspaceman
Copy link
Copy Markdown
Contributor

Issue #, if available:

Fixes #1202

Description of changes:

When deserializeShape() encounters invalid input (e.g., a nested struct in a list with missing required fields), the builder throws a SerializationException mid-parse. The finally block in JsonCodec.deserializeShape() then calls close() on the deserializer, which triggers an NPE that suppresses the original helpful exception.

The NPE occurs in JacksonJsonDeserializer.close() because:

  1. parser.nextToken() returns non-null (unconsumed tokens remain after the aborted parse)
  2. parser.close() is called, then parser = null
  3. describeToken() is called, which dereferences the now-null parser → NPE

Fix:

  • In JacksonJsonDeserializer.close(), capture the token description before nulling the parser reference.
  • In JsonCodec.deserializeShape(), use closeQuietly() on the error path so exceptions from close() don't suppress the original deserialization/validation exception.

Test: Added deserializeShapeWithNestedMissingRequiredFieldReportsFieldName which fails without this fix (NPE suppresses the "Missing required members" exception) and passes with it.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@etspaceman etspaceman force-pushed the fix/json-deserializer-close-npe branch from ed9e262 to 09850be Compare May 22, 2026 16:44
@etspaceman
Copy link
Copy Markdown
Contributor Author

Whoops - forgot spotless. Updated.

… errors (smithy-lang#1202)

When deserializeShape() encounters invalid input (e.g., a nested struct
with missing required fields), the builder throws a SerializationException
mid-parse. The finally block then calls close(), which:

1. Calls parser.nextToken() (returns non-null due to unconsumed tokens)
2. Calls parser.close() then sets parser = null
3. Calls describeToken() which dereferences the now-null parser -> NPE

This NPE suppresses the original helpful exception (e.g.,
"Missing required members: [field]").

Fix:
- In JacksonJsonDeserializer.close(), capture the token description
  before nulling the parser reference.
- In JsonCodec.deserializeShape(), use closeQuietly() on the error path
  so that exceptions from close() don't suppress the original
  deserialization/validation exception.
@adwsingh adwsingh force-pushed the fix/json-deserializer-close-npe branch from 09850be to 9d0ddb1 Compare May 22, 2026 23:21
@adwsingh
Copy link
Copy Markdown
Contributor

Thanks for the fix @etspaceman . Did you get a chance to take the new SmithyJson serde for a spin? Its opt in right now and we are looking for some real world feedback. Its much faster than Jackson see #1148

You can opt in by setting the system property -Dsmithy-java.json-provider=smithy.

@etspaceman
Copy link
Copy Markdown
Contributor Author

No I haven't! Id love to give it a try. Will report back when I do.

@adwsingh adwsingh merged commit 8173842 into smithy-lang:main May 22, 2026
3 checks passed
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.

JsonCodec.deserializeShape() NPE suppresses validation exceptions on invalid input

2 participants