fix(indexing): reject blank document input consistently across formats - #105
Open
adityamparikh wants to merge 1 commit into
Open
fix(indexing): reject blank document input consistently across formats#105adityamparikh wants to merge 1 commit into
adityamparikh wants to merge 1 commit into
Conversation
adityamparikh
force-pushed
the
fix/document-creator-null-validation
branch
from
May 2, 2026 17:04
51c5b8d to
ac5e90d
Compare
adityamparikh
force-pushed
the
fix/document-creator-null-validation
branch
from
August 18, 2026 21:25
ac5e90d to
a94d1f3
Compare
3 tasks
adityamparikh
force-pushed
the
fix/document-creator-null-validation
branch
from
August 18, 2026 21:31
a94d1f3 to
a46d9b1
Compare
JSON and CSV input was unvalidated: `create(null)` threw NPE and `create("")`
produced an empty document list, so `index-json-documents` reported
"Successfully indexed 0 of 0 documents" for input the caller never sent. XML
already rejected the same input, but from IndexingDocumentCreator rather than
the creator itself, so the three formats disagreed on both behaviour and
location.
Move the check to the SolrDocumentCreator contract as a shared
`requireContent(content, format)` helper and call it from all three creators.
Every format now throws DocumentProcessingException with the identical message
shape "<FORMAT> input cannot be null or empty" — the wording XML already used,
so existing assertions are unchanged.
The null half of the check is deliberate rather than redundant defensive
coding: the package is @NullMarked with NullAway as a build error, but that
analysis only binds callers the compiler can see. These creators are reached
from @mcptool methods whose arguments the Spring AI annotation runtime resolves
reflectively from the request's argument map, so a missing JSON value arrives
as null regardless of the annotation.
Also corrects the SolrDocumentCreator javadoc, which documented three mutually
exclusive contracts (handle null gracefully / return empty list / throw
IllegalArgumentException), none of which matched the implementations.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Aditya Parikh <aditya.m.parikh@gmail.com>
adityamparikh
force-pushed
the
fix/document-creator-null-validation
branch
from
August 19, 2026 11:58
a46d9b1 to
9fc28df
Compare
This was referenced Aug 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Rebased onto
mainafter #176, which added blank checks to the JSON and CSV creators. That left the three formats with three different messages for the same condition, and JSON/CSV still NPE on null:mainmainjson.isBlank()JSON input cannot be emptycsv.isBlank()CSV input cannot be emptyxml == null || xml.trim().isEmpty()XML input cannot be null or emptyXML's check also lives in
IndexingDocumentCreatorrather than the creator itself, so the formats disagree on location as well as wording.Changes
SolrDocumentCreatorcontract as a sharedrequireContent(content, format)helper; call it from all three creators."<FORMAT> input cannot be null or empty"— the wording XML already used, so existingXmlIndexingTestassertions are unchanged.SolrDocumentCreatorjavadoc, which documented three mutually exclusive contracts (handle null gracefully / return empty list / throwIllegalArgumentException), none matching the implementations....FromJson(null)NullPointerExceptionDocumentProcessingException: JSON input cannot be null or empty...FromJson("")DocumentProcessingException: JSON input cannot be emptyDocumentProcessingException: JSON input cannot be null or empty...FromCsv(null)NullPointerExceptionDocumentProcessingException: CSV input cannot be null or empty...FromCsv("")DocumentProcessingException: CSV input cannot be emptyDocumentProcessingException: CSV input cannot be null or empty...FromXml(null or "")DocumentProcessingException: XML input cannot be null or emptyWhy a runtime null check in
@NullMarkedcodeThe package is
@NullMarkedwith NullAway wired as a build error, so this may look redundant — that is presumably why #176 wrotejson.isBlank()with no null guard. But NullAway is a closed-world compile-time analysis: it only binds callers the compiler can see, and emits no runtime check (unlike Kotlin, which compilesIntrinsics.checkNotNullParameterinto public API boundaries).These creators are reached from
@McpToolmethods whose arguments the Spring AI annotation runtime resolves reflectively:AbstractMcpToolMethodCallbacklooks each parameter up in the request's argument map and passes the result straight tobuildTypedArgument, which returnsnullfor a null input. A missing or null JSON value therefore arrives asnullregardless of the annotation.@McpToolParam(required = true)only marks the parameter required in the advertised JSON schema; the server does not validate incoming arguments against it.The rationale is recorded on
requireContentso it doesn't get "cleaned up" later.Test plan
./gradlew buildpasses (rebased ontoc1c2a8e)JsonIndexingTest(4 tests) and 3 addedCsvIndexingTestcases mirror the existing XML null/empty/whitespace trioXmlIndexingTest(16 tests) unchanged and greenCompanion to #108, which applies the same treatment to collection-name validation and uses the same message wording.
🤖 Generated with Claude Code