{"record":{"id":"ff1f4856650ff541","repo":"pentaho/pentaho-kettle","slug":"session-recovery-failed-or-was-canceled","errorCode":null,"errorMessage":"Session recovery failed or was canceled","messagePattern":"Session recovery failed or was canceled","errorType":"exception","errorClass":"KettleRepositoryLostException","httpStatus":null,"severity":"error","filePath":"plugins/repositories/core/src/main/java/org/pentaho/di/ui/repo/timeout/RepositorySessionTimeoutHandler.java","lineNumber":120,"sourceCode":"    Spoon spoon = Spoon.getInstance();\n\n    sessionTimeoutHandler.getRepositoryConnectController().setRelogin( true );\n\n    disconnectRepository( spoon );\n\n    // Show login dialog - browser auth will be selected automatically if previously used\n    boolean loginSuccessful = sessionTimeoutHandler.showLoginScreen( sessionTimeoutHandler.getRepositoryConnectController() );\n\n    if ( loginSuccessful && spoon.getRepository() != null && spoon.getRepository().isConnected() ) {\n      return reconnectAndRetry( method, args );\n    }\n    // Must run on the UI thread since setRepository may trigger UI updates (tree refresh, tab changes)\n    if ( spoon.getDisplay() != null ) {\n      spoon.getDisplay().syncExec( () -> spoon.setRepository( null ) );\n    } else {\n      spoon.setRepository( null );\n    }\n    throw new KettleRepositoryLostException( \"Session recovery failed or was canceled\" );\n  }\n\n  private void disconnectRepository( Spoon spoon ) {\n    if ( spoon.getRepository() != null ) {\n      try {\n        spoon.getRepository().disconnect();\n      } catch ( Exception e ) {\n        // Ignore errors during emergency disconnect\n      }\n    }\n  }\n\n  private Object reconnectAndRetry( Method method, Object[] args )\n      throws SessionRecoveryRetryException {\n    try {\n      ConnectionManager.getInstance().reset();\n    } catch ( Exception ce ) {\n      // Intentionally ignore cache reset errors - they should not prevent reconnection","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/plugins/repositories/core/src/main/java/org/pentaho/di/ui/repo/timeout/RepositorySessionTimeoutHandler.java#L102-L138","documentation":"RepositorySessionTimeoutHandler.handleSessionExpiry clears the repository from Spoon (setRepository(null)) and throws KettleRepositoryLostException('Session recovery failed or was canceled') when automatic session recovery could not be completed or the user declined the recovery prompt. After this, the current repository connection is gone and the operation that hit the expiry cannot proceed.","triggerScenarios":"A repository invocation fails with a session-timeout/lost-session error; the handler tries to recover (re-login) but recovery fails, is not possible, or the user cancels the recovery dialog.","commonSituations":"Long-running Spoon session whose Pentaho server session timed out; user dismisses the re-login dialog; re-login attempts fail due to wrong credentials or server unavailability.","solutions":["Reconnect to the repository manually (Connect dialog) and redo the operation","Check credentials/server availability if re-login attempts fail repeatedly","Increase the server session timeout to reduce frequency of expiry","Save work frequently so a session loss does not lose changes"],"exampleFix":"// before\nrepository.someOp(); // throws KettleRepositoryLostException on unrecoverable expiry\n// after\ntry {\n  repository.someOp();\n} catch ( KettleRepositoryLostException e ) {\n  promptUserToReconnect(); // guide user through manual reconnect\n}","handlingStrategy":"try-catch","validationCode":"// detect lost-session style failures before deep stacks\nboolean isRepositoryLost( Throwable t ) {\n  while ( t != null ) {\n    if ( t instanceof KettleRepositoryLostException ) return true;\n    t = t.getCause();\n  }\n  return false;\n}","typeGuard":"boolean isRepositoryLost( Throwable t ) {\n  while ( t != null ) {\n    if ( t instanceof KettleRepositoryLostException ) return true;\n    t = t.getCause();\n  }\n  return false;\n}","tryCatchPattern":"try {\n  repository.someOp();\n} catch ( KettleRepositoryLostException e ) {\n  // repository is disconnected; guide user to reconnect, do not retry blindly\n  spoon.promptRepositoryConnect();\n}","preventionTips":["Increase server session timeout for long Spoon sessions","Periodically ping the repository during long operations to keep the session alive","Save work incrementally so session loss does not lose changes","Educate users not to dismiss the recovery dialog when a long operation is running"],"tags":["session","timeout","repository","swt-ui"],"backgroundTag":"session-expired","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}