{"record":{"id":"767452960816b9f6","repo":"pentaho/pentaho-kettle","slug":"unable-to-get-a-list-of-repositories-to-locate-repository","errorCode":null,"errorMessage":"Unable to get a list of repositories to locate repository '${repositoryName}'","messagePattern":"Unable to get a list of repositories to locate repository '(.+?)'","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/job/JobExecutionConfiguration.java","lineNumber":491,"sourceCode":"    Node repNode = XMLHandler.getSubNode( trecNode, \"repository\" );\n    if ( repNode != null ) {\n      String repositoryName = XMLHandler.getTagValue( repNode, \"name\" );\n      String username = XMLHandler.getTagValue( repNode, \"login\" );\n      String password = Encr.decryptPassword( XMLHandler.getTagValue( repNode, \"password\" ) );\n      connectRepository( repositoryName, username, password );\n    }\n\n  }\n\n  public Repository connectRepository( String repositoryName, String username, String password ) throws KettleException {\n    // Verify that the repository exists on the slave server...\n    //\n    RepositoriesMeta repositoriesMeta = new RepositoriesMeta();\n    repositoriesMeta.getLog().setLogLevel( log.getLogLevel() );\n    try {\n      repositoriesMeta.readData();\n    } catch ( Exception e ) {\n      throw new KettleException( \"Unable to get a list of repositories to locate repository '\" + repositoryName + \"'\" );\n    }\n    return connectRepository( repositoriesMeta, repositoryName, username, password );\n  }\n\n  public Repository connectRepository( RepositoriesMeta repositoriesMeta, String repositoryName, String username, String password ) throws KettleException {\n    RepositoryMeta repositoryMeta = repositoriesMeta.findRepository( repositoryName );\n    if ( repositoryMeta == null ) {\n      log.logBasic( \"I couldn't find the repository with name '\" + repositoryName + \"'\" );\n      return null;\n    }\n\n    Repository rep = PluginRegistry.getInstance().loadClass( RepositoryPluginType.class, repositoryMeta,\n        Repository.class );\n    rep.init( repositoryMeta );\n\n    try {\n      rep.connect( username, password );\n      log.logBasic( \"Connected to \" + repositoryName + \" as \" + username );","sourceCodeStart":473,"sourceCodeEnd":509,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/job/JobExecutionConfiguration.java#L473-L509","documentation":"connectRepository(repositoriesMeta...) path: before locating a named repository, the code reads the local repositories.xml list via repositoriesMeta.readData(). If that read throws for any reason, the library throws a KettleException with this message naming the repository it was trying to find. Notably the original exception is swallowed, so the cause is not chained.","triggerScenarios":"Calling connectRepository(repositoriesMeta, repositoryName, username, password) overload when readData() fails: missing/corrupt ~/.kettle/repositories.xml, unreadable home directory, malformed XML, or inaccessible plugin-providing repository drivers.","commonSituations":"Headless servers where $HOME/.kettle/repositories.xml is absent; wrong KETTLE_HOME; permissions changed on the user home; corrupted repositories.xml after an upgrade.","solutions":["Verify ~/.kettle/repositories.xml (or $KETTLE_HOME/.kettle/repositories.xml) exists and is valid XML.","Run Spoon/Kitchen once as the same user to generate repositories.xml, or copy a known-good one.","Check file permissions on the .kettle directory for the executing user (service accounts often differ from your login).","Because the cause is not chained, reproduce readData() separately (new RepositoriesMeta().readData()) to surface the underlying exception.","If no repository is needed, skip repository connection and run the job from file instead."],"exampleFix":"// before: relying on implicit repositories.xml in service context\nRepository repo = execCfg.connectRepository(\"prod-repo\", \"user\", \"pass\");\n// after: ensure KETTLE_HOME and repositories.xml first\nSystem.setProperty(\"KETTLE_HOME\", \"/opt/pentaho/.kettle-home\");\nRepositoriesMeta rm = new RepositoriesMeta();\nrm.readData(); // surface real error here\nRepository repo = execCfg.connectRepository(rm, \"prod-repo\", \"user\", \"pass\");","handlingStrategy":"fallback","validationCode":"File reposXml = new File(System.getProperty(\"KETTLE_HOME\", System.getProperty(\"user.home\")) + \"/.kettle/repositories.xml\");\nif (!reposXml.canRead()) throw new IllegalStateException(\"repositories.xml missing/unreadable: \" + reposXml);","typeGuard":null,"tryCatchPattern":"try {\n  repo = execCfg.connectRepository(\"prod-repo\", user, pass);\n} catch (KettleException e) {\n  if (e.getMessage().startsWith(\"Unable to get a list of repositories\")) {\n    repo = loadRepositoryFromFileFallback();\n  } else { throw e; }\n}","preventionTips":["Point KETTLE_HOME explicitly for service accounts and bake a valid repositories.xml into the image.","Check permissions on .kettle after provisioning.","Because the cause is swallowed, call RepositoriesMeta.readData() in a health check to surface the real error.","Avoid repository connections in contexts where none is needed."],"tags":["repository","configuration","filesystem"],"backgroundTag":"file-read-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"}