pentaho/pentaho-kettle · error · KettleException
MetaInjectMeta.Exception.UnableToLoadTransformationFromFile
Error message
MetaInjectMeta.Exception.UnableToLoadTransformationFromFile
What it means
During MetaInjectMeta's loadTransformation handling (specification method FILE), the mapping transformation is instantiated from a real filename via new TransMeta(...). Any failure reading/parsing that .ktr is wrapped in a KettleException using the localized message MetaInjectMeta.Exception.UnableToLoadTransformationFromFile with the filename. The injection transformation cannot resolve its target transformation.
Solutions
- Verify the file exists at the resolved path by logging the substituted realFilename.
- Fix variable values (e.g. ${Internal.Transformation.Filename.Directory}) used in the filename.
- Check file read permissions for the user running PDI.
- Open the target .ktr in Spoon to confirm it is not corrupt.
Example fix
// before: relative path that breaks at runtime
String file = "transforms/child.ktr";
// after: anchor to the transformation's own directory
String file = "${Internal.Transformation.Filename.Directory}/child.ktr"; Defensive patterns
Strategy: validation
Validate before calling
// Resolve and check the file before triggering the load
String real = space.environmentSubstitute(injectMeta.getFileName());
File f = new File(real);
if (!f.exists() || !f.canRead()) {
throw new IllegalStateException("Mapping transformation not readable: " + real);
} Try / catch
try {
loadMappingTransformation();
} catch (KettleException e) {
logError("Could not load transformation from file " + realFilename + ": " + e.getCause(), e);
} Prevention
- Use ${Internal.Transformation.Filename.Directory} for relative references
- Verify file existence after variable substitution
- Check OS-level read permissions for the PDI run user
When it happens
Trigger: loadTransformation/MetaInjectMeta initialization with specificationMethod=FILENAME where realFilename points to a missing, unreadable, or malformed .ktr file, or variables (tmpSpace substitution) resolve to a wrong path.
Common situations: Moved/renamed transformation files; relative paths broken because the job runs from a different working directory; missing environment variables in the substitution space; permission issues on the file.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- MetaInjectMeta.Exception.UnableToLoadTrans
- StepWithMappingMeta.Exception.UnableToLoadTrans
- Unable to load transformation
- AccessInput.Log.RequiredFilesMissing
- ChangeFileEncoding.Error.SourceFileNotExists
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/cf9be5ac14811514.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/meta-inject/impl/src/main/java/org/pentaho/di/trans/steps/metainject/MetaInjectMeta.java:562
String tmpFilename =
realFilename.substring( realFilename.lastIndexOf( "/" ) + 1, realFilename.indexOf( "."
+ Const.STRING_TRANS_DEFAULT_EXT ) );
String dirStr = realFilename.substring( 0, realFilename.lastIndexOf( "/" ) );
RepositoryDirectoryInterface dir = rep.findDirectory( dirStr );
mappingTransMeta = rep.loadTransformation( tmpFilename, dir, null, true, null );
} catch ( KettleException ke2 ) {
// fall back to try loading from file system (transMeta is going to be null)
}
}
}
}
if ( mappingTransMeta == null ) {
mappingTransMeta = new TransMeta( bowl, realFilename, metaStore, rep, false, tmpSpace, null );
mappingTransMeta.getLogChannel().logDetailed( "Loading Mapping from repository",
"Mapping transformation was loaded from XML file [" + realFilename + "]" );
}
} catch ( Exception e ) {
throw new KettleException( BaseMessages.getString( PKG,
"MetaInjectMeta.Exception.UnableToLoadTransformationFromFile", realFilename ), e );
}
break;
case REPOSITORY_BY_NAME:
String realTransname = tmpSpace.environmentSubstitute( injectMeta.getTransName() );
String realDirectory = tmpSpace.environmentSubstitute( injectMeta.getDirectoryPath() );
if ( rep != null ) {
if ( !Utils.isEmpty( realTransname ) && !Utils.isEmpty( realDirectory ) && rep != null ) {
RepositoryDirectoryInterface repdir = rep.findDirectory( realDirectory );
if ( repdir != null ) {
try {
// reads the last revision in the repository...
//
// TODO: FIXME: see if we need to pass external MetaStore references to the repository?
//
mappingTransMeta = rep.loadTransformation( realTransname, repdir, null, true, null );
View on GitHub (pinned to f3058517a1)