pentaho/pentaho-kettle · warning · KettleRepositoryLostException
User canceled repository reconnection after session timeout
Error message
User canceled repository reconnection after session timeout
What it means
SessionTimeoutHandler.handleLoginCanceled is invoked when the user cancels the re-login dialog during session recovery. It disconnects the repository (ignoring disconnect errors) and throws KettleRepositoryLostException('User canceled repository reconnection after session timeout'). The repository connection is lost and the original operation cannot complete.
Solutions
- Reconnect to the repository via the Connect dialog and repeat the operation
- Save unsaved work before closing, since the repository is disconnected after cancel
- Increase the server session timeout so the dialog appears less often
- Handle KettleRepositoryLostException in automation/embedded scenarios to prompt reconnection programmatically
Example fix
// before
repository.loadData(...); // aborts with KettleRepositoryLostException if user cancels re-login
// after
try {
repository.loadData(...);
} catch ( KettleRepositoryLostException e ) {
spoon.promptRepositoryConnect(); // offer manual reconnect before proceeding
} Defensive patterns
Strategy: fallback
Validate before calling
// detect the cancel path before losing work
boolean isUserCanceledReconnect( Throwable t ) {
while ( t != null ) {
if ( t instanceof KettleRepositoryLostException
&& t.getMessage() != null
&& t.getMessage().contains( "canceled" ) ) return true;
t = t.getCause();
}
return false;
} Try / catch
try {
handler.performLoginAndReinvoke( objectToHandle, method, args );
} catch ( KettleRepositoryLostException e ) {
// user canceled: save work locally, then offer manual reconnect
saveWorkLocally();
spoon.promptRepositoryConnect();
} Prevention
- Save work frequently so a canceled recovery does not lose changes
- Increase server session timeout to make the dialog rare
- For automation, avoid interactive timeout handlers; use non-blocking reconnect logic
- Clearly label the recovery dialog so users know canceling disconnects the repository
When it happens
Trigger: Session timeout dialog shown to the user; user clicks Cancel/close; handler disconnects the repository and throws KettleRepositoryLostException up through performLoginAndReinvoke.
Common situations: User away from the machine when the timeout dialog appears; user intentionally declines re-login; dialog dismissed accidentally during a long-running transformation.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Session recovery failed or was canceled
- Attempting to create PDI Repository with no Active…
- Failed to create repository for user
- Failed to retry repository operation after reconnect
- Unable to invoke repository operation after reconnect
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/a29b9743a70d4fcd.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/repositories/core/src/main/java/org/pentaho/di/ui/repo/timeout/SessionTimeoutHandler.java:218
* {@link KettleRepositoryLostException} to stop the current operation.
*/
private void handleLoginCanceled() throws KettleRepositoryLostException {
log.logBasic( "User canceled reconnection after session expiry - disconnecting repository" );
try {
Spoon spoon = getSpoon();
if ( spoon != null ) {
spoon.getDisplay().syncExec( () -> {
try {
spoon.closeRepository();
} catch ( Exception ex ) {
log.logError( "Error closing repository after user canceled reconnection", ex );
}
} );
}
} catch ( Exception e ) {
log.logError( "Error during repository disconnect after cancel", e );
}
throw new KettleRepositoryLostException( "User canceled repository reconnection after session timeout" );
}
boolean lookupForConnectTimeoutError( Throwable root ) {
while ( root != null ) {
if ( EXCEPTION_CLASS_NAME.equals( root.getClass().getSimpleName() ) ) {
String errorMessage = root.getMessage();
if ( errorMessage.contains( RepositoryConnectController.ERROR_401 ) ) {
return true;
} else {
return false;
}
} else {
root = root.getCause();
}
}
return false;View on GitHub (pinned to f3058517a1)