{"record":{"id":"147f2fea308b674b","repo":"pentaho/pentaho-kettle","slug":"error-saving-job","errorCode":null,"errorMessage":"Error saving job","messagePattern":"Error saving job","errorType":"exception","errorClass":"InvocationTargetException","httpStatus":null,"severity":"error","filePath":"ui/src/main/java/org/pentaho/di/ui/job/dialog/JobSaveProgressDialog.java","lineNumber":59,"sourceCode":"  /**\n   * Creates a new dialog that will handle the wait while saving a job...\n   */\n  public JobSaveProgressDialog( Shell shell, Repository rep, JobMeta jobInfo, String versionComment ) {\n    this.shell = shell;\n    this.rep = rep;\n    this.jobMeta = jobInfo;\n    this.versionComment = versionComment;\n  }\n\n  public boolean open() {\n    boolean retval = true;\n\n    IRunnableWithProgress op = new IRunnableWithProgress() {\n      public void run( IProgressMonitor monitor ) throws InvocationTargetException, InterruptedException {\n        try {\n          rep.save( jobMeta, versionComment, new ProgressMonitorAdapter( monitor ) );\n        } catch ( KettleException e ) {\n          throw new InvocationTargetException( e, \"Error saving job\" );\n        }\n      }\n    };\n\n    try {\n      ProgressMonitorDialog pmd = new ProgressMonitorDialog( shell );\n      pmd.run( true, true, op );\n    } catch ( InvocationTargetException e ) {\n      new ErrorDialog( shell, \"Error saving job\", \"An error occured saving the job!\", e );\n      retval = false;\n    } catch ( InterruptedException e ) {\n      new ErrorDialog( shell, \"Error saving job\", \"An error occured saving the job!\", e );\n      retval = false;\n    }\n\n    return retval;\n  }\n}","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/ui/src/main/java/org/pentaho/di/ui/job/dialog/JobSaveProgressDialog.java#L41-L77","documentation":"JobSaveProgressDialog wraps the repository save of a JobMeta inside an IRunnableWithProgress run on a ProgressMonitorDialog. If rep.save(jobMeta, ...) throws a KettleException, it is rethrown as an InvocationTargetException with the message 'Error saving job'. The dialog then surfaces the cause, so the real reason is always in the nested KettleException.","triggerScenarios":"Calling the dialog's open() when the repository save fails: repository connection dropped, user lacks write permission in the target directory, duplicate job name/version conflicts, or versionComment handling rejected by the repository.","commonSituations":"Saving to a disconnected repository after a network hiccup; saving into a read-only repository or a directory without write access; repository commit failure (e.g. database down); concurrent modification of the same job by another user.","solutions":["Inspect the InvocationTargetException's cause (KettleException) for the real repository error message.","Verify the repository connection is alive (reconnect via rep.connect()) before retrying the save.","Check that the target repository directory grants write permission to the logged-in user.","Resolve name/version conflicts (rename the job or adjust the version comment) and retry."],"exampleFix":"// before\nrep.save( jobMeta, versionComment, new ProgressMonitorAdapter( monitor ) );\n// after\nif ( !rep.isConnected() ) {\n  rep.connect( username, password );\n}\nrep.save( jobMeta, versionComment == null ? \"\" : versionComment, new ProgressMonitorAdapter( monitor ) );","handlingStrategy":"try-catch","validationCode":"if ( rep == null || !rep.isConnected() ) {\n  throw new IllegalStateException( \"Repository not connected before saving job\" );\n}\nif ( jobMeta == null || jobMeta.getName() == null || jobMeta.getName().isEmpty() ) {\n  throw new IllegalStateException( \"Job must have a name before saving\" );\n}","typeGuard":null,"tryCatchPattern":"try {\n  new JobSaveProgressDialog( shell, rep, jobMeta, versionComment ).open();\n} catch ( InvocationTargetException e ) {\n  Throwable cause = e.getCause();\n  logError( \"Job save failed: \" + cause.getMessage(), cause );\n  MessageBox mb = new MessageBox( shell, SWT.ICON_ERROR );\n  mb.setMessage( BaseMessages.getString( PKG, \"JobLog.JobSaveFailed\", cause.getMessage() ) );\n  mb.open();\n}","preventionTips":["Check repository connectivity before opening the save dialog.","Ensure the user has write permission on the target repository directory.","Always log e.getCause() — the wrapper message hides the real KettleException.","Handle version-comment conflicts by prompting the user for a new comment or name."],"tags":["kettle","repository","save","job","ui-dialog"],"backgroundTag":"file-write-failed","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"}