{"record":{"id":"1fe0a752970f431d","repo":"pentaho/pentaho-kettle","slug":"jobjob-exception-missingjobfilename","errorCode":null,"errorMessage":"JobJob.Exception.MissingJobFileName","messagePattern":"JobJob\\.Exception\\.MissingJobFileName","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/base/MetaFileLoaderImpl.java","lineNumber":376,"sourceCode":"\n    return realFilename;\n  }\n\n  boolean hasUnresolvedFilenamePlaceholders( String filename ) {\n    return filename != null && ( filename.contains( \"${\" ) || filename.contains( \"%%\" ) );\n  }\n\n  private T getMetaFromRepository( Bowl bowl, Repository rep, CurrentDirectoryResolver r, String metaPath, VariableSpace tmpSpace )\n    throws KettleException {\n    String realName = \"\";\n    String realDirectory = \"/\";\n\n    if ( StringUtils.isBlank( metaPath ) ) {\n      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() ) {","sourceCodeStart":358,"sourceCodeEnd":394,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/base/MetaFileLoaderImpl.java#L358-L394","documentation":"Thrown by MetaFileLoaderImpl.getMetaFromRepository when a job is configured to load from a repository but the meta path (repository path + job name) is blank or null. This is the JobMeta branch of the same blank-metaPath check that produces error 615, using the JobJob 'missing job file name' message. Reached via getMetaForEntry.","triggerScenarios":"Calling getMetaForEntry/getMetaFromRepository for a JobMeta with specificationMethod=REPOSITORY_BY_NAME while metaPath is null/blank — e.g. the job entry's repository path field is empty, or a ${VARIABLE} in the path resolved to empty during environmentSubstitute.","commonSituations":"Job executor entries pointing at the repository with the 'Job' path left blank; unset environment variables yielding an empty path after substitution; migrated metadata missing the repository reference; programmatic use of the loader API without setting metaName/directory.","solutions":["Set the job's repository path (metaPath, e.g. '/home/admin/myJob') on the job entry meta before execution.","Define any variables used in the path (run configuration, job parameters, kettle.properties) so substitution produces a non-empty value.","If the job should load from a file, switch specificationMethod to FILENAME and provide a valid .kjb path.","Validate with StringUtils.isBlank(metaPath) in calling code before invoking the loader and report a clearer message."],"exampleFix":"// before\njobEntry.setSpecificationMethod(REPOSITORY_BY_NAME); // path left empty\nloader.getMetaForEntry(bowl, rep, metaStore, space);\n\n// after\njobEntry.setSpecificationMethod(REPOSITORY_BY_NAME);\njobEntry.setJobName(\"myJob\");\njobEntry.setDirectory(\"/home/admin\"); // metaPath = \"/home/admin/myJob\"\nloader.getMetaForEntry(bowl, rep, metaStore, space);","handlingStrategy":"validation","validationCode":"// Java caller, before invoking the loader\nif (StringUtils.isBlank(jobEntry.getMetaPath())) {\n  throw new IllegalArgumentException(\n    \"Job repository path is blank; set the /dir/name path for the child job\");\n}","typeGuard":"boolean hasRepositoryPath(JobExecutorMeta m) {\n  return m != null && StringUtils.isNotBlank(m.getDirectory() + m.getJobName());\n}","tryCatchPattern":"try {\n  T meta = loader.getMetaForEntry(bowl, rep, metaStore, space);\n} catch (KettleException e) {\n  if (String.valueOf(e.getMessage()).contains(\"MissingJobFileName\")) {\n    throw new ConfigurationException(\"Child job path not configured: \" + entryName, e);\n  }\n  throw e;\n}","preventionTips":["Ensure every Job Executor entry has the repository directory and job name set when using repository specification.","Resolve variables in configured paths during build/CI validation of job metadata.","Keep a metadata export review step that checks repository paths are non-empty before release."],"tags":["kettle","pdi","repository","missing-configuration"],"backgroundTag":"missing-required-argument","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"}