apache/shardingsphere · error · MCPExecutionModeRequiredException
%s execution_mode is required.
Error message
%s execution_mode is required.
What it means
database_gateway_execute_update requires an explicit execution_mode argument ('execute' or 'preview') because updates are side-effecting; resolveExecutionMode throws MCPExecutionModeRequiredException when the argument is empty. This forces the caller to consciously opt into executing or previewing rather than mutating by default. The exception lists the accepted modes and includes preview-oriented suggested arguments.
Source
Thrown at mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/ExecuteUpdateToolHandler.java:100
}
return SQLExecutionPayload.executed(requestContext.getExecutionFacade().execute(
SQLExecutionToolHandlerSupport.createExecutionRequest(requestContext.getSessionIdentity().getSessionId(), toolArguments, sql, CoreToolNames.EXECUTE_UPDATE)));
}
private ClassificationResult checkUpdateStatement(final MCPFeatureRequestContext requestContext, final MCPToolArguments toolArguments, final String sql) {
ClassificationResult classificationResult = SQLExecutionToolHandlerSupport.analyze(requestContext, toolArguments, sql);
if (SQLExecutionToolHandlerSupport.isQueryStatement(classificationResult)) {
throw new SQLToolMismatchException("database_gateway_execute_update does not accept read-only SQL. Use database_gateway_execute_query for read-only SQL.",
CoreToolNames.EXECUTE_UPDATE, CoreToolNames.EXECUTE_QUERY, classificationResult,
createQuerySuggestedArguments(toolArguments, classificationResult));
}
return classificationResult;
}
private String resolveExecutionMode(final MCPToolArguments toolArguments) {
String result = toolArguments.getStringArgument(MCPPayloadFieldNames.EXECUTION_MODE);
if (result.isEmpty()) {
throw new MCPExecutionModeRequiredException(CoreToolNames.EXECUTE_UPDATE, EXECUTION_MODES, createPreviewSuggestedArguments(toolArguments));
}
if (EXECUTION_MODE_EXECUTE.equals(result) || EXECUTION_MODE_PREVIEW.equals(result)) {
return result;
}
throw new MCPInvalidExecutionModeException(CoreToolNames.EXECUTE_UPDATE, EXECUTION_MODES, createPreviewSuggestedArguments(toolArguments));
}
private MCPSuccessPayload createPreviewResponse(final MCPToolArguments toolArguments, final ClassificationResult classificationResult) {
Map<String, Object> result = new LinkedHashMap<>(17, 1F);
result.put("response_mode", MCPResponseMode.PREVIEW);
result.put("result_kind", RESULT_KIND_PREVIEW);
result.put(MCPPayloadFieldNames.EXECUTION_MODE, EXECUTION_MODE_PREVIEW);
result.put("preview_semantics", "classification_only");
result.put("affected_rows_estimated", false);
result.put("status", "PREVIEWED");
result.put("would_execute", false);
result.put("statement_class", classificationResult.getStatementClass().name().toLowerCase(Locale.ENGLISH));
result.put("statement_type", classificationResult.getStatementType());View on GitHub (pinned to e952770a21)
Solutions
- Add "execution_mode": "execute" (to apply) or "execution_mode": "preview" (to classify-only) to the arguments.
- Refresh the client/agent prompt with the tool's current input schema.
- Default to 'preview' when unsure — it performs classification only and never executes.
Example fix
// before
await tools.call('database_gateway_execute_update', { sql: "DELETE FROM t" }); // execution_mode is required
// after
await tools.call('database_gateway_execute_update', { sql: "DELETE FROM t", execution_mode: 'preview' });
// verified safe -> rerun with execution_mode: 'execute' Defensive patterns
Strategy: validation
Validate before calling
// Always set a mode; default to preview when not verified
function updateArgs(sql, { dryRun = true } = {}) {
return { sql, execution_mode: dryRun ? 'preview' : 'execute' };
}
const args = updateArgs(sql); // execution_mode present by construction Type guard
function hasExecutionMode(args) {
return typeof args.execution_mode === 'string' && args.execution_mode.length > 0;
} Try / catch
try {
return await tools.call('database_gateway_execute_update', args);
} catch (e) {
if (/execution_mode is required/.test(e.message)) {
return tools.call('database_gateway_execute_update', { ...args, execution_mode: 'preview' });
}
throw e;
} Prevention
- Make execution_mode a required field in your wrapper around execute_update.
- Default to 'preview' and only flip to 'execute' after reviewing the preview.
- Refresh tool schemas in agent prompts after server upgrades.
When it happens
Trigger: Calling database_gateway_execute_update without the execution_mode argument at all, or with an empty string value.
Common situations: LLM omitting execution_mode from the arguments map; client built before the argument became required (schema change); JSON payload dropping empty-string fields; copy-pasted call examples without the field.
Related errors
- %s execution_mode must be one of %s.
- Completion argument `%s` is not declared for %s `%s`.
- %s must be an integer between %d and %d.
- %s execution_mode is required.
- %s execution_mode must be one of %s.
AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14).
Data as JSON: /api/errors/d5e1ba7f89691932.
Report an issue: GitHub.