OtterMind/Chat2DB · error · BusinessException

routine.operation.parameterLoadFailed

routine.operation.parameterLoadFailed

Error message

routine.operation.parameterLoadFailed

What it means

Thrown by queryRoutineParameters when loading a routine's parameter metadata fails for any reason. The original exception is wrapped in BusinessException('routine.operation.parameterLoadFailed', {causeMessage}) so the caller gets a localized message while the root SQLException is preserved as the cause. It fires during previewInvocation when building the parameter list.

Source

Thrown at chat2db-community-server/chat2db-community-plugins/chat2db-community-mysql/src/main/java/ai/chat2db/plugin/mysql/MysqlRoutineManager.java:321

            if (FUNCTION.equals(routineType)) {
                return metaData.getFunctionParameters(connection, databaseName, StringUtils.trimToNull(operation.getSchemaName()),
                                routineName)
                        .stream()
                        .map(mysqlRoutineConverter::functionParameter2routineParameter)
                        .filter(Objects::nonNull)
                        .sorted((left, right) -> Integer.compare(left.ordinalPosition(), right.ordinalPosition()))
                        .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;
    }

View on GitHub (pinned to 5ee1e990e7)

Solutions

  1. Grant the invoking user SELECT privilege on the routine metadata (information_schema / mysql.proc) or the routine itself.
  2. Verify the routine name and database in the operation match an existing routine before previewing.
  3. Inspect BusinessException.getCause() for the underlying SQLException to get the SQL state and vendor error code.
  4. Ensure the connection is still open and not shared across threads during the metadata call.

Example fix

// before
routineManager.previewInvocation(connection, operation);

// after
try {
    SqlPreview preview = routineManager.previewInvocation(connection, operation);
} catch (BusinessException e) {
    if ("routine.operation.parameterLoadFailed".equals(e.getCode())) {
        Throwable cause = e.getCause();
        log.warn("Cannot load params for {}: {}", operation.getRoutineName(),
            cause == null ? e.getMessage() : cause.getMessage());
    }
    throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Ensure the routine exists and the user has metadata privileges before previewing.
if (!routineExistsByName(connection, db, name, type)) {
    throw new IllegalArgumentException("routine not found");
}

Try / catch

try {
    routineManager.previewInvocation(connection, operation);
} catch (BusinessException e) {
    if ("routine.operation.parameterLoadFailed".equals(e.getCode())) {
        Throwable cause = e.getCause();
        log.warn("param load failed: {}", cause == null ? e.getMessage() : cause.getMessage());
    }
    throw e;
}

Prevention

When it happens

Trigger: previewInvocation → queryRoutineParameters calls metaData.getFunctionParameters/getProcedureParameters, which throws. Typical causes: the connected user lacks SELECT on mysql.proc / information_schema, the routine name does not resolve, the connection is closed, or the JDBC driver cannot parse the parameter metadata.

Common situations: Invoking (previewing) a procedure/function with a low-privilege connection; referencing a routine that was renamed or dropped; a network blip dropping the connection mid-query; an older MySQL Connector/J that returns incomplete routine metadata.

Related errors


AI-assisted analysis of OtterMind/Chat2DB@5ee1e990e7 (2026-08-14). Data as JSON: /api/errors/07c6a6f5100bbff6. Report an issue: GitHub.