apache/shardingsphere · error · MCPInvalidRequestException
Completion argument `%s` is not declared for %s `%s`.
Error message
Completion argument `%s` is not declared for %s `%s`.
What it means
MCPCompletionService validates that the argument being completed is actually declared by the target completion descriptor (a tool's or prompt's declared argument list). If argumentName is not in descriptor.getArguments(), it throws MCPInvalidRequestException formatted with the argument name, reference type ('tool'/'prompt') and reference name. This guards against completion requests for arguments the referenced tool/prompt never declares.
Source
Thrown at mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/completion/MCPCompletionService.java:124
Collection<MCPCompletionCandidate> candidates = handlerResult.getCandidates();
int maxValues = Math.min(MAX_VALUES_LIMIT, 0 == descriptor.getMaxValues() ? DEFAULT_MAX_VALUES : descriptor.getMaxValues());
List<MCPCompletionCandidate> filteredCandidates = candidates.stream().filter(each -> matchesPrefix(each.getValue(), prefix)).sorted(createCandidateComparator(prefix)).toList();
String matchStrategy = "prefix";
if (filteredCandidates.isEmpty() && !prefix.isEmpty()) {
filteredCandidates = candidates.stream().filter(each -> matchesContains(each.getValue(), prefix)).sorted(createCandidateComparator(prefix)).toList();
matchStrategy = "contains_fallback";
}
List<MCPCompletionCandidate> returnedCandidates = filteredCandidates.stream().limit(maxValues).toList();
CompletionMetadataContext metadataContext = new CompletionMetadataContext(descriptor, argumentName, prefix, matchStrategy, actualContextArguments, handlerResult,
filteredCandidates, returnedCandidates);
Map<String, Object> meta = createMeta(metadataContext);
return new MCPCompletionResult(returnedCandidates.stream().map(MCPCompletionCandidate::getValue).toList(), filteredCandidates.size(), filteredCandidates.size() > returnedCandidates.size(),
meta);
}
private void validateDeclaredArgument(final MCPCompletionTargetDescriptor descriptor, final String argumentName) {
if (!descriptor.getArguments().contains(argumentName)) {
throw new MCPInvalidRequestException(String.format("Completion argument `%s` is not declared for %s `%s`.",
Objects.toString(argumentName, ""), descriptor.getReferenceType(), descriptor.getReference()));
}
}
private void mergeInferredContextArguments(final Map<String, String> contextArguments, final Map<String, Object> inferredContextArguments) {
for (Entry<String, Object> entry : inferredContextArguments.entrySet()) {
if (Objects.toString(contextArguments.get(entry.getKey()), "").isEmpty()) {
contextArguments.put(entry.getKey(), Objects.toString(entry.getValue(), ""));
}
}
}
private Comparator<MCPCompletionCandidate> createCandidateComparator(final String prefix) {
String normalizedPrefix = prefix.toLowerCase(Locale.ENGLISH);
return Comparator.comparingInt((MCPCompletionCandidate each) -> getExactMatchRank(each, normalizedPrefix))
.thenComparing(this::compareUpdateTime)
.thenComparing(each -> each.getValue().toLowerCase(Locale.ENGLISH))
.thenComparing(MCPCompletionCandidate::getValue);View on GitHub (pinned to e952770a21)
Solutions
- List the tool/prompt (tools/list, prompts/list) and use an argument name from its current declared arguments.
- Fix typos in argument.name so it matches the tool input schema exactly (case-sensitive).
- If the client caches schemas, refresh it after upgrading the MCP server.
- Server-side, add the missing argument to the tool descriptor if it was intended to be completable.
Example fix
// before
{ "method": "completion/complete",
"params": { "ref": { "type": "ref/tool", "name": "database_gateway_execute_query" },
"argument": { "name": "maxRow", "prefix": "1" } } } // typo -> error
// after
{ "method": "completion/complete",
"params": { "ref": { "type": "ref/tool", "name": "database_gateway_execute_query" },
"argument": { "name": "max_rows", "prefix": "1" } } } Defensive patterns
Strategy: validation
Validate before calling
// Validate against the live tool/prompt schema before completing
const tools = (await mcp.request('tools/list')).tools;
const tool = tools.find(t => t.name === params.ref.name);
const declared = tool ? Object.keys(tool.inputSchema?.properties ?? {}) : [];
if (!declared.includes(params.argument.name)) {
throw new Error(`argument '${params.argument.name}' not declared; choose from: ${declared.join(', ')}`);
}
return mcp.request('completion/complete', params); Type guard
function isDeclaredCompletionArgument(toolsList, refName, argName) {
const tool = toolsList.find(t => t.name === refName);
return Boolean(tool) && Object.keys(tool.inputSchema?.properties ?? {}).includes(argName);
} Try / catch
try {
return await mcp.request('completion/complete', params);
} catch (e) {
if (/is not declared for/.test(e.message)) { /* fix argument name from tools/list and retry once */ }
throw e;
} Prevention
- Always read argument names from tools/list/prompts/list instead of hardcoding.
- Refresh cached schemas after MCP server upgrades.
- Match argument names case-sensitively.
- Validate argument names against the tool input schema before calling completion.
When it happens
Trigger: Calling the completion/complete endpoint with ref.name='some_tool' and argument.name='foo' when some_tool's input schema does not declare an argument named 'foo' — usually a typo, a stale client hardcoding an argument that was renamed, or completing against the wrong reference.
Common situations: Argument renamed between MCP server versions while the client caches the old schema; misspelled argument names; copying a completion request example that targets a different tool; drifting tool schemas between environments.
Related errors
- %s execution_mode is required.
- %s execution_mode must be one of %s.
- %s must be an integer between %d and %d.
- Completion request limit of %d per minute exceeded for MCP s
- database_gateway_execute_query only supports parser-approved
AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14).
Data as JSON: /api/errors/28d50ee8702beb6b.
Report an issue: GitHub.