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

  1. Set the transformation's repository path (metaPath / filename field, e.g. '/home/admin/myTrans') on the step meta before executing.
  2. If the path uses variables, define those variables in the run configuration, job parameters, or kettle.properties so substitution yields a non-empty value.
  3. 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.
  4. 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

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


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)