{"record":{"id":"d707fc9d024991a8","repo":"pentaho/pentaho-kettle","slug":"unable-to-find-repository-directory-realdirectory","errorCode":null,"errorMessage":"Unable to find repository directory [<realDirectory>]","messagePattern":"Unable to find repository directory \\[<realDirectory>\\]","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/base/MetaFileLoaderImpl.java","lineNumber":390,"sourceCode":"      if ( isTransMeta() ) {\n        throw new KettleException(\n          BaseMessages.getString( persistentClass, \"JobTrans.Exception.MissingTransFileName\" ) );\n      } else {\n        throw new KettleException(\n          BaseMessages.getString( persistentClass, \"JobJob.Exception.MissingJobFileName\" ) );\n      }\n    }\n\n    int index = metaPath.lastIndexOf( RepositoryFile.SEPARATOR );\n    if ( index != -1 ) {\n      realName = metaPath.substring( index + 1 );\n      realDirectory = index == 0 ? RepositoryFile.SEPARATOR : metaPath.substring( 0, index );\n    }\n    realDirectory = r.normalizeSlashes( realDirectory );\n\n    RepositoryDirectoryInterface repositoryDirectory = rep.loadRepositoryDirectoryTree().findDirectory( realDirectory );\n    if ( repositoryDirectory == null ) {\n      throw new KettleException( \"Unable to find repository directory [\" + Const.NVL( realDirectory, \"\" ) + \"]\" );\n    }\n\n    T theMeta = null;\n    if ( isTransMeta() ) {\n      theMeta = (T) rep.loadTransformation( bowl, realName, repositoryDirectory, null, true, null, tmpSpace );\n    } else {\n      JobMeta jobMeta = rep.loadJob( realName, repositoryDirectory, null, null, tmpSpace );\n      if ( jobMeta != null ) {\n        jobMeta.initializeVariablesFrom( tmpSpace );\n      }\n      theMeta = (T) jobMeta;\n    }\n    return theMeta;\n  }\n\n  private T attemptCacheRead( String realFilename ) {\n    if ( !useCache || metaFileCache == null ) {\n      return null;","sourceCodeStart":372,"sourceCodeEnd":408,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/base/MetaFileLoaderImpl.java#L372-L408","documentation":"Thrown by MetaFileLoaderImpl.getMetaFromRepository after resolving realDirectory from the meta path: rep.loadRepositoryDirectoryTree().findDirectory(realDirectory) returned null, meaning the directory does not exist in the repository (or the user lacks access to it). The loader aborts before attempting to load the transformation/job object. This is a repository lookup failure, not a file-system failure.","triggerScenarios":"Calling getMetaForEntry with a repository metaPath whose directory portion (everything before the last '/') does not match any directory in the repository tree — e.g. path '/home/admin/myTrans' when '/home/admin' was deleted/renamed, path typed with wrong casing or missing normalization, or referencing a directory in a different repository than the one connected.","commonSituations":"Repository content reorganized (folders renamed/moved) breaking saved paths; connecting to the wrong repository or a fresh one that lacks the referenced folders; permission-restricted directories invisible to the current user; typos or stale ${VARIABLE} values producing an invalid directory path; Kettle 8+ repository API changes around directory resolution.","solutions":["Verify the directory exists: browse the repository tree in Spoon or call rep.loadRepositoryDirectoryTree().findDirectory(dir) yourself and correct the path in the step/entry configuration.","Confirm you are connected to the intended repository and that the user has read permission on the folder.","Re-point the step/entry to the moved/renamed location, or recreate the folder at the referenced path.","Resolve any variables in the path and check normalization (double slashes, leading/trailing separators) against normalizeSlashes behavior.","Pre-check in calling code: resolve the directory before loading and give a clear message listing the requested path."],"exampleFix":"// before\nRepositoryDirectoryInterface dir = rep.loadRepositoryDirectoryTree().findDirectory(\"/home/admin\");\n// dir == null -> KettleException \"Unable to find repository directory [/home/admin]\"\n\n// after\nRepositoryDirectoryInterface dir = rep.loadRepositoryDirectoryTree().findDirectory(realDirectory);\nif (dir == null) {\n  throw new KettleException(\"Directory \" + realDirectory + \" not found in repository \" + rep.getName()\n    + \". Available: \" + rep.loadRepositoryDirectoryTree().getDisplayText(\"/\"));\n}","handlingStrategy":"try-catch","validationCode":"// Java caller, pre-flight directory check\nRepositoryDirectoryInterface dir =\n  rep.loadRepositoryDirectoryTree().findDirectory(realDirectory);\nif (dir == null) {\n  throw new IllegalArgumentException(\"Repository directory missing: \" + realDirectory\n    + \" in repository \" + rep.getName());\n}","typeGuard":null,"tryCatchPattern":"try {\n  T meta = loader.getMetaForEntry(bowl, rep, metaStore, space);\n} catch (KettleException e) {\n  if (e.getMessage() != null && e.getMessage().startsWith(\"Unable to find repository directory\")) {\n    throw new ConfigurationException(\"Repository folder missing/renamed: \" + e.getMessage(), e);\n  }\n  throw e;\n}","preventionTips":["Avoid renaming/deleting repository folders without updating all steps/entries that reference them (search metadata exports for the old path).","Confirm repository connection settings (which repo, which user) match the environment where paths were authored.","Verify path normalization: no double slashes, correct leading '/', and case matching the repository tree.","Pin environment variables used in directory paths per environment (dev/qa/prod) so they resolve to existing folders."],"tags":["kettle","pdi","repository","directory-not-found"],"backgroundTag":"directory-not-found","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"}