pentaho/pentaho-kettle · error · KettleException
JobTrans.Exception.MissingTransFileName
Error message
JobTrans.Exception.MissingTransFileName
What it means
Thrown by MetaFileLoaderImpl.getMetaFromRepository when a transformation is configured to load from a repository but the meta path (repository path + object name) is blank or null. The loader cannot construct a repository lookup without a path, so it fails fast with the JobTrans 'missing transformation file name' message. It guards the TransMeta branch of the blank-metaPath check in getMetaFromRepository, reached via getMetaForEntry.
Solutions
- Set the transformation's repository path (metaPath / filename field, e.g. '/home/admin/myTrans') on the step meta before executing.
- If the path uses variables, define those variables in the run configuration, job parameters, or kettle.properties so substitution yields a non-empty value.
- Verify the step is configured for the intended specification method: switch to FILENAME with a valid .ktr path if you meant to load from a file rather than the repository.
- Guard callers: check StringUtils.isBlank(metaPath) before invoking getMetaForEntry and surface a clear validation message.
Example fix
// before
JobTransMeta meta = new JobTransMeta(); // repository path never set
loader.getMetaForEntry(bowl, rep, metaStore, space);
// after
stepMeta.setTransName("myTrans");
stepMeta.setDirectory("/home/admin"); // or metaPath = "/home/admin/myTrans"
if (StringUtils.isNotBlank(metaPath)) {
loader.getMetaForEntry(bowl, rep, metaStore, space);
} Defensive patterns
Strategy: validation
Validate before calling
// Java caller, before invoking the loader
if (StringUtils.isBlank(stepMeta.getMetaPath())) {
throw new IllegalArgumentException(
"Transformation repository path is blank; set the /dir/name path for the child transformation");
} Type guard
boolean hasRepositoryPath(JobTransMeta m) {
return m != null && StringUtils.isNotBlank(m.getMetaPath());
} Try / catch
try {
T meta = loader.getMetaForEntry(bowl, rep, metaStore, space);
} catch (KettleException e) {
if (String.valueOf(e.getMessage()).contains("MissingTransFileName")) {
throw new ConfigurationException("Child transformation path not configured: " + stepName, e);
}
throw e;
} Prevention
- Always populate the repository path field on transformation-executor/mapping steps; validate job metadata before deployment.
- Audit ${VARIABLE} usage in paths and ensure they are defined in run configurations or kettle.properties.
- Add a startup smoke test that resolves every child-transformation path with environmentSubstitute and fails fast on blanks.
When it happens
Trigger: Calling getMetaForEntry/getMetaFromRepository with specificationMethod=REPOSITORY_BY_NAME (repository-based resolution) while metaPath resolves to null or whitespace — typically when the transformation filename/path field was never set or an ${VARIABLE} in the path resolved to an empty string.
Common situations: Transformation executor/mapping steps where the 'Transformation' path field was left blank; a variable like ${INTERNAL_TRANS_PATH} unset in the run environment so environmentSubstitute yields empty; metadata exported/imported without the repository path populated; calling the loader API programmatically with an empty path string.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- JobJob.Exception.MissingJobFileName
- ColumnExistsMeta.Exception.UnableToSaveStepInfo
- ColumnExistsMeta.Exception.UnexpectedErrorReadingStepInfo
- CreditCardValidatorMeta.Exception.UnexpectedErrorReadingStepInfo
- CreditCardValidatorMeta.Exception.UnableToSaveStepInfo
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/2a5bbdb3b1fa8296.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/base/MetaFileLoaderImpl.java:373
if ( hasUnresolvedFilenamePlaceholders( realFilename ) && space != null && tmpSpace != null && space != tmpSpace ) {
realFilename = tmpSpace.environmentSubstitute( filename );
}
return realFilename;
}
boolean hasUnresolvedFilenamePlaceholders( String filename ) {
return filename != null && ( filename.contains( "${" ) || filename.contains( "%%" ) );
}
private T getMetaFromRepository( Bowl bowl, Repository rep, CurrentDirectoryResolver r, String metaPath, VariableSpace tmpSpace )
throws KettleException {
String realName = "";
String realDirectory = "/";
if ( StringUtils.isBlank( metaPath ) ) {
if ( isTransMeta() ) {
throw new KettleException(
BaseMessages.getString( persistentClass, "JobTrans.Exception.MissingTransFileName" ) );
} else {
throw new KettleException(
BaseMessages.getString( persistentClass, "JobJob.Exception.MissingJobFileName" ) );
}
}
int index = metaPath.lastIndexOf( RepositoryFile.SEPARATOR );
if ( index != -1 ) {
realName = metaPath.substring( index + 1 );
realDirectory = index == 0 ? RepositoryFile.SEPARATOR : metaPath.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, "" ) + "]" );
}View on GitHub (pinned to f3058517a1)