OtterMind/Chat2DB · error · BusinessException
routine.operation.typeUnsupported
routine.operation.typeUnsupported
Error message
routine.operation.typeUnsupported
What it means
Thrown by normalizeRoutineType when operation.getRoutineType(), after trim+uppercase, is neither FUNCTION nor PROCEDURE. This is a hard validation: only those two routine kinds are supported by the MySQL routine manager. Any other value (including null, empty, 'TRIGGER', 'EVENT') is rejected before any SQL is built.
Source
Thrown at chat2db-community-server/chat2db-community-plugins/chat2db-community-mysql/src/main/java/ai/chat2db/plugin/mysql/MysqlRoutineManager.java:328
.toList();
}
return metaData.getProcedureParameters(connection, databaseName, StringUtils.trimToNull(operation.getSchemaName()),
routineName)
.stream()
.map(mysqlRoutineConverter::procedureParameter2routineParameter)
.filter(Objects::nonNull)
.sorted((left, right) -> Integer.compare(left.ordinalPosition(), right.ordinalPosition()))
.toList();
} catch (Exception e) {
throw new BusinessException("routine.operation.parameterLoadFailed", new Object[]{e.getMessage()}, e);
}
}
private String normalizeRoutineType(String routineType) {
String normalized = StringUtils.trimToEmpty(routineType).toUpperCase(Locale.ROOT);
if (!FUNCTION.equals(normalized) && !PROCEDURE.equals(normalized)) {
throw new BusinessException("routine.operation.typeUnsupported");
}
return normalized;
}
private String requireRoutineName(RoutineOperation operation) {
String routineName = StringUtils.trimToEmpty(operation.getRoutineName());
if (StringUtils.isBlank(routineName)) {
throw new BusinessException("routine.operation.nameRequired");
}
return routineName;
}
private String requireDatabaseName(RoutineOperation operation) {
String databaseName = StringUtils.trimToEmpty(operation.getDatabaseName());
if (StringUtils.isBlank(databaseName)) {
throw new BusinessException("routine.operation.databaseRequired");
}
return databaseName;View on GitHub (pinned to 5ee1e990e7)
Solutions
- Set operation.setRoutineType("FUNCTION") or "PROCEDURE" (case-insensitive) before calling.
- Validate the routineType at the request boundary and reject unsupported kinds with a clear message.
- If the value comes from metadata, map it to FUNCTION/PROCEDURE and skip other kinds.
- Confirm the RoutineOperation builder is not leaving routineType unset.
Example fix
// before
operation.setRoutineType(rawType);
routineManager.previewInvocation(connection, operation);
// after
String type = StringUtils.trimToEmpty(rawType).toUpperCase(Locale.ROOT);
if (!"FUNCTION".equals(type) && !"PROCEDURE".equals(type)) {
throw new IllegalArgumentException("Unsupported routine type: " + rawType);
}
operation.setRoutineType(type);
routineManager.previewInvocation(connection, operation); Defensive patterns
Strategy: validation
Validate before calling
String t = StringUtils.trimToEmpty(rawType).toUpperCase(Locale.ROOT);
if (!"FUNCTION".equals(t) && !"PROCEDURE".equals(t)) {
throw new IllegalArgumentException("Unsupported routine type: " + rawType);
}
operation.setRoutineType(t); Type guard
static boolean isSupportedRoutineType(String type) {
String t = StringUtils.trimToEmpty(type).toUpperCase(Locale.ROOT);
return "FUNCTION".equals(t) || "PROCEDURE".equals(t);
} Prevention
- Restrict the routine-type picker to FUNCTION/PROCEDURE.
- Map metadata routine types to FUNCTION/PROCEDURE at the boundary.
- Reject unsupported kinds early with a clear validation message.
- Never leave routineType unset on a RoutineOperation.
When it happens
Trigger: Calling any routine-manager entry point (previewInvocation, previewMigration, executeMigration) with operation.getRoutineType() returning a value other than FUNCTION/PROCEDURE, case-insensitively.
Common situations: Frontend sends the routine type from a dropdown that includes unsupported kinds; a null/blank routineType field in the request payload; a copy of the operation object left with a default/null routineType; mislabeling an EVENT or TRIGGER as a routine.
Related errors
- routine.operation.nameRequired
- routine.operation.databaseRequired
- routine.operation.ddlRequired
- Existing routine definition is empty
- Existing routine definition does not contain routine name
AI-assisted analysis of OtterMind/Chat2DB@5ee1e990e7 (2026-08-14).
Data as JSON: /api/errors/928753bf30d59612.
Report an issue: GitHub.