pentaho/pentaho-kettle · error · KettleException

Unable to find repository directory [

Error message

Unable to find repository directory [

What it means

getJobMetaFromRepository() parses a repository path (transPath like /dir/subdir/jobname), normalizes the directory part, and looks it up via rep.loadRepositoryDirectoryTree().findDirectory(realDirectory). When no repository directory matches, it throws this KettleException embedding the directory that was not found.

Solutions

  1. Verify the directory path in the Job entry exists in the repository (Browse button) and correct it
  2. Fix or define the variables that build the directory path at runtime
  3. Recreate renamed/moved directories in the repository or update all referencing job entries
  4. Confirm the repository connection is live so loadRepositoryDirectoryTree() returns the full tree

Example fix

// before: Directory: ${JOB_DIR}
// after: ensure it resolves and exists before execute
String dir = environmentSubstitute(getVariable("JOB_DIR", "/prod"));
if (rep.loadRepositoryDirectoryTree().findDirectory(dir) == null) {
  setVariable("JOB_DIR", "/prod");
}
Defensive patterns

Strategy: validation

Validate before calling

String dir = environmentSubstitute(jobEntry.getDirectory());
RepositoryDirectoryInterface tree = rep.loadRepositoryDirectoryTree();
if (dir != null && !dir.isEmpty() && tree.findDirectory(dir) == null) {
  throw new IllegalArgumentException("Repository directory does not exist: " + dir);
}

Try / catch

try {
  JobMeta jm = jobEntry.getJobMeta(rep, metaStore, space);
} catch (KettleException e) {
  if (e.getMessage().startsWith("Unable to find repository directory")) {
    // correct the directory path or create it in the repository
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling getJobMeta with specificationMethod REPOSITORY_BY_NAME where the directory field (or a combined path variable) resolves to a path absent from the repository tree — e.g. '/production/monthly' renamed to '/prod/monthly', or a variable substituting to an empty/garbage path.

Common situations: Repository directories reorganized between environments; variable ${JOB_DIR} undefined so the path is wrong; case-sensitive path mismatch on the repository DB; repository not connected so the directory tree fails to load.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/da44e31962083f69. Report an issue: GitHub.

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/job/entries/job/JobEntryJob.java:1437

  public JobMeta getJobMeta( Repository rep, VariableSpace space ) throws KettleException {
    parentJobMeta.getMetaFileCache( ); //Get the cache from the parent or create it
    return getJobMeta( rep, getMetaStore(), space );
  }

  protected JobMeta getJobMetaFromRepository( Repository rep, CurrentDirectoryResolver r, String transPath, VariableSpace tmpSpace ) throws KettleException {
    String realJobName = "";
    String realDirectory = "/";

    int index = transPath.lastIndexOf( RepositoryFile.SEPARATOR );
    if ( index != -1 ) {
      realJobName = transPath.substring( index + 1 );
      realDirectory = index == 0 ? RepositoryFile.SEPARATOR : transPath.substring( 0, index );
    }

    realDirectory = r.normalizeSlashes( realDirectory );
    RepositoryDirectoryInterface repositoryDirectory = rep.loadRepositoryDirectoryTree().findDirectory( realDirectory );
    if ( repositoryDirectory == null ) {
      throw new KettleException( "Unable to find repository directory [" + Const.NVL( realDirectory, "" ) + "]" );
    }
    JobMeta jobMeta = rep.loadJob( realJobName, repositoryDirectory, null, null ); //reads
    if ( jobMeta != null ) {
      jobMeta.initializeVariablesFrom( tmpSpace );
    }
    return jobMeta;
  }

  public JobMeta getJobMeta( Repository rep, IMetaStore metaStore, VariableSpace space ) throws KettleException {
    try {
      IMetaFileLoader<JobMeta> metaFileLoader = new MetaFileLoaderImpl<>( this, specificationMethod );
      JobMeta jobMeta = metaFileLoader.getMetaForEntry( parentJobMeta.getBowl(), rep, metaStore, space );

      if ( jobMeta != null ) {
        jobMeta.setRepository( rep );
        jobMeta.setMetaStore( metaStore );
      }

View on GitHub (pinned to f3058517a1)