fix: validate collection name consistently across all MCP tool methods - #108
Open
adityamparikh wants to merge 1 commit into
Open
fix: validate collection name consistently across all MCP tool methods#108adityamparikh wants to merge 1 commit into
adityamparikh wants to merge 1 commit into
Conversation
adityamparikh
force-pushed
the
fix/unified-collection-validation
branch
from
May 2, 2026 17:04
14c39e5 to
d8ddc16
Compare
adityamparikh
force-pushed
the
fix/unified-collection-validation
branch
from
June 14, 2026 03:39
d8ddc16 to
2c77c92
Compare
adityamparikh
force-pushed
the
fix/unified-collection-validation
branch
from
August 18, 2026 21:25
2c77c92 to
d918d29
Compare
4 tasks
adityamparikh
force-pushed
the
fix/unified-collection-validation
branch
from
August 18, 2026 21:31
d918d29 to
5f0eb18
Compare
Only createCollection and the two schema-modification tools validated the
collection name. checkHealth, getCollectionStats, search, the three
index*Documents tools, getSchema and getSchemaResource accepted null or blank
and failed downstream — a null collection reaches SolrJ and silently targets
the client's default collection rather than reporting a bad argument.
The message was already duplicated on main: a BLANK_COLLECTION_NAME_ERROR
constant in CollectionService and a copied string literal in SchemaService's
private requireCollection. Extract one shared
ToolArguments.requireCollection(String) in the util package and route all
eleven call sites through it, so the four services cannot drift apart.
Message wording is aligned with the document-creator family
("<Subject> cannot be null or empty"), which also covers SchemaService's
sibling requireNonEmpty helper.
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. MCP tool methods are invoked
reflectively by the Spring AI annotation runtime, which resolves each parameter
with a plain lookup against the request's argument map and passes the result
straight through — a missing or null JSON value therefore arrives as null no
matter what the annotations declare. @McpToolParam(required = true) only marks
the parameter required in the advertised JSON schema; the server does not
validate incoming arguments against it.
CollectionNameValidationTest asserts all nine entry points against the shared
constant rather than a copied literal.
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/unified-collection-validation
branch
from
August 19, 2026 11:58
5f0eb18 to
98c8ece
Compare
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
Only
createCollectionand the two schema-modification tools validated the collection name.checkHealth,getCollectionStats,search, the threeindex*Documentstools,getSchemaandgetSchemaResourceaccepted null or blank and failed downstream — and a null collection reaching SolrJ silently targets the client's default collection rather than reporting a bad argument.The message was also already duplicated on
main: aBLANK_COLLECTION_NAME_ERRORconstant inCollectionServiceand a copied string literal inSchemaService's privaterequireCollection.Changes
ToolArguments.requireCollection(String)into theutilpackage and route all eleven call sites through it, so the four services cannot drift apart.SchemaService's private duplicate is removed."Collection name cannot be null or empty", aligned with the document-creator family in fix(indexing): reject blank document input consistently across formats #105.SchemaService's siblingrequireNonEmptyhelper is aligned to the same wording.Coverage after this change:
CollectionServicecreateCollection*,getCollectionStats,checkHealthIndexingServiceindexJsonDocuments,indexCsvDocuments,indexXmlDocumentsSchemaServicegetSchema,getSchemaResource,addFields,addFieldTypesSearchServicesearch* already validated on
main; switched to the shared helper.Why a runtime null check in
@NullMarkedcodeThe package is
@NullMarkedwith NullAway wired as a build error, so this may look redundant. It isn't — NullAway is a closed-world compile-time analysis and only binds callers the compiler can see.MCP tool methods are invoked reflectively by the Spring AI annotation runtime:
AbstractMcpToolMethodCallbackresolves each parameter with a plain lookup against the request's argument map and passes the result straight tobuildTypedArgument, which returnsnullfor a null input. A missing or null JSON value therefore arrives asnullno matter what the annotations declare.@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
ToolArgumentsso it doesn't get "cleaned up" later.Test plan
./gradlew buildpassesCollectionNameValidationTest(9 tests, all green) asserts every entry point against the shared constant rather than a copied literal — that is what keeps the services from driftingCompanion to #105, which applies the same treatment to document-input validation and uses the same message wording.
🤖 Generated with Claude Code