{"record":{"id":"4d46f340fda97378","repo":"pentaho/pentaho-kettle","slug":"repository-required","errorCode":null,"errorMessage":"Repository required.","messagePattern":"Repository required\\.","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/www/RunJobServlet.java","lineNumber":327,"sourceCode":"          PKG, \"RunJobServlet.Error.UnableToFindJob\", serverConfig.getRepositoryId() ) ) );\n        return;\n      }\n      response.setStatus( HttpServletResponse.SC_INTERNAL_SERVER_ERROR );\n      out.println( new WebResult( WebResult.STRING_ERROR, BaseMessages.getString(\n        PKG, \"RunJobServlet.Error.UnexpectedError\", Const.CR + Const.getStackTracker( ex ) ) ) );\n    }\n  }\n\n  protected void runJob( Job job ) {\n    // Execute the transformation...\n    //\n    job.start();\n  }\n\n  private JobMeta loadJob( Repository repository, String job, VariableSpace parentVariableSpace ) throws KettleException {\n\n    if ( repository == null ) {\n      throw new KettleException( \"Repository required.\" );\n    } else {\n\n      synchronized ( repository ) {\n        // With a repository we need to load it from /foo/bar/Transformation\n        // We need to extract the folder name from the path in front of the\n        // name...\n        //\n        String directoryPath;\n        String name;\n        int lastSlash = job.lastIndexOf( RepositoryDirectory.DIRECTORY_SEPARATOR );\n        if ( lastSlash < 0 ) {\n          directoryPath = \"/\";\n          name = job;\n        } else {\n          directoryPath = job.substring( 0, lastSlash );\n          name = job.substring( lastSlash + 1 );\n        }\n        RepositoryDirectoryInterface directory =","sourceCodeStart":309,"sourceCodeEnd":345,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/www/RunJobServlet.java#L309-L345","documentation":"RunJobServlet.loadJob requires a Repository to load a job by repository path; if repository is null it throws KettleException 'Repository required.' The servlet's job-loading path was invoked without a repository context.","triggerScenarios":"GET /kettle/runJob/ where the servlet resolves the job through a Repository but the repository reference is null — the Carte server has no repository configured (repositories.xml not defined/loaded) while the request expects repository-based lookup.","commonSituations":"Standalone Carte without a configured repository but calling runJob with a repository-style path; repositories.xml missing credentials or not present in KETTLE_HOME; internal call path (jobMeta) passing null repository.","solutions":["Configure a repository for the Carte server (define repositories.xml in .kettle/KETTLE_HOME with valid connection details).","Use the file-based variant instead: runJob with a filename (input file parameter) rather than a repository path, or use RegisterPackageServlet for file uploads.","Verify the repository connection credentials/login so the servlet can construct the Repository object rather than passing null.","If embedding the servlet, pass a non-null Repository (e.g. KettleDatabaseRepository initialized and connected) into loadJob."],"exampleFix":"// before\n// repositories.xml absent; servlet gets repository == null\n// after\n// ~/.kettle/repositories.xml with <repository><name>prod</name>... </repository>,\n// and request uses repository-based path: /kettle/runJob/?job=/home/admin/myjob&...","handlingStrategy":"validation","validationCode":"import java.io.File;\nboolean repositoryConfigured = new File(System.getProperty(\"user.home\") + \"/.kettle/repositories.xml\").exists();\nboolean useFileMode = repositoryConfigured ? false : true; // fall back to file-based runJob","typeGuard":null,"tryCatchPattern":"try {\n  String res = httpGet(\"/kettle/runJob/?job=/home/admin/myjob&...\");\n} catch (KettleException e) {\n  if (e.getMessage().contains(\"Repository required.\")) {\n    // fall back to file-based invocation\n    res = httpGet(\"/kettle/runJob/?\" + fileParams);\n  }\n}","preventionTips":["Configure repositories.xml in $KETTLE_HOME/.kettle before using repository-path endpoints.","Use the file/filename parameters for standalone Carte without a repository.","Verify repository credentials resolve a connected Repository at servlet startup.","Document which Carte endpoints require a repository and gate client calls accordingly."],"tags":["repository","job","servlet","configuration"],"backgroundTag":"missing-required-config-field","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"}