pentaho/pentaho-kettle · error · KettleDatabaseException
BaseMessages.getString( packageClass, key, parameters )…
Error message
BaseMessages.getString( packageClass, key, parameters ) (localized message, dynamic)
What it means
DatabaseLogExceptionFactory's ThrowableBehaviour registers a database log record and throws a KettleDatabaseException whose message is produced by BaseMessages.getString(packageClass, key, parameters) — a localized message looked up from a message bundle with optional {0}-style parameters. It is thrown so the caller sees a localized, formatted error while the same text is written to the log channel.
Solutions
- Fix the packageClass/key pair so it matches an entry in the bundle's messages.properties files.
- Verify the parameter count matches the placeholders in the localized message.
- Check the kettle locales directory contains the properties file for packageClass on the classpath.
- Catch KettleDatabaseException at the call site and log the actual cause if the localized message is unhelpful.
Example fix
// before DatabaseLogExceptionFactory.getExceptionBehaviour().registerException(log, PKG, "MyPlugin.WrongKey.Error"); // after DatabaseLogExceptionFactory.getExceptionBehaviour().registerException(log, PKG, "MyPlugin.ConnectionFailed.Error", tableName);
Defensive patterns
Strategy: try-catch
Validate before calling
// validate the key exists before calling String msg = BaseMessages.getString( PKG, "MyPlugin.ConnectionFailed.Error" ); if ( msg.startsWith( "!" ) ) throw new IllegalStateException( "Missing message key" );
Try / catch
try {
behaviour.registerException( log, PKG, KEY, params );
} catch ( KettleDatabaseException e ) {
log.logError( "DB operation failed", e );
// inspect e.getMessage() and the message bundle
} Prevention
- Keep message keys referenced from code in sync with messages.properties
- Unit-test localized lookups for every key used with the exception factory
- Match parameter count to bundle placeholders
- Use constants for keys instead of inline strings
When it happens
Trigger: Calling DatabaseLogExceptionFactory.registerException(log, packageClass, key, parameters...) (or the overload with a cause Exception) where the given key exists or is missing in the packageClass message bundle; any runtime failure in BaseMessages lookup formatting also surfaces here.
Common situations: Plugin code using the exception factory with a typo'd message key or wrong packageClass, or passing parameters that don't match the bundle placeholders, yielding 'Message not found in key' style output wrapped in a KettleDatabaseException.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- A connection of type PALO is expected
- A connection of type PALO is expected
- A deadlock was detected between steps
- A server socket allocation always has to accompanied by a…
- A server socket allocation always has to accompanied by a…
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/ec75a193c442e3af.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/pentaho/di/core/database/util/DatabaseLogExceptionFactory.java:121
private static DatabaseInterfaceExtended extractDatabase( LogTableCoreInterface table ) {
DatabaseInterfaceExtended result = null;
if ( table != null && table.getDatabaseMeta() != null ) {
DatabaseInterface databaseInterface = table.getDatabaseMeta().getDatabaseInterface();
result =
databaseInterface instanceof DatabaseInterfaceExtended ? (DatabaseInterfaceExtended) databaseInterface : null;
}
return result;
}
/**
* Throw exception back to caller, this will be logged somewhere else.
*/
private static class ThrowableBehaviour implements LogExceptionBehaviourInterface {
@Override
public void registerException( LogChannelInterface log, Class<?> packageClass, String key, String... parameters )
throws KettleDatabaseException {
throw new KettleDatabaseException( BaseMessages.getString( packageClass, key, parameters ) );
}
@Override public void registerException( LogChannelInterface log, Exception e, Class<?> packageClass, String key,
String... parameters ) throws KettleDatabaseException {
throw new KettleDatabaseException( BaseMessages.getString( packageClass, key, parameters ), e );
}
}
/**
* Suppress exception, but still add a log record about it
*/
private static class SuppressBehaviour implements LogExceptionBehaviourInterface {
@Override
public void registerException( LogChannelInterface log, Class<?> packageClass, String key, String... parameters ) {
log.logError( BaseMessages.getString( packageClass, key, parameters ) );
}
View on GitHub (pinned to f3058517a1)