pentaho/pentaho-kettle · error · KettleException
JobTrans.Exception.ReferencedTransformationIdIsNull
Error message
JobTrans.Exception.ReferencedTransformationIdIsNull
What it means
A job/trans job-entry is configured to locate its referenced object by repository object ID (specificationMethod = REPOSITORY_BY_REFERENCE), but that ID (metaObjectId) is null. The loader validates this in getMetaForEntry before attempting any repository load and throws a KettleException immediately. The message key differs by entry type: 'JobTrans...' for transformation entries and 'JobJob...' for job entries.
Solutions
- Set the repository object ID on the entry before running: call entry.setSpecificationMethod(SPECIFICATION_METHOD.REPOSITORY_BY_REFERENCE) and entry.setObjectId(repositoryObjectId) with a valid ObjectId obtained from the repository.
- If the object should be referenced by name instead, switch the entry to REPOSITORY_BY_NAME and set directory + name (or to FILENAME with a file path).
- Open the job in Spoon and re-select the referenced transformation/job on the job entry dialog so the object ID is repopulated, then save.
- Verify the kjb file/repo metadata actually contains the reference ID element; if missing, recreate or re-export the job.
Example fix
// before JobEntryTrans jet = new JobEntryTrans(); jet.setSpecificationMethod( JobEntryInterface.SPECIFICATION_METHOD.REPOSITORY_BY_REFERENCE ); // objectId never set -> KettleException at runtime // after jet.setSpecificationMethod( JobEntryInterface.SPECIFICATION_METHOD.REPOSITORY_BY_REFERENCE ); RepositoryObject ros = rep.getObjectInformation( objectId, RepositoryObjectType.TRANSFORMATION ); jet.setObjectId( ros.getObjectId() ); // valid, non-null ObjectId
Defensive patterns
Strategy: validation
Validate before calling
// before executing the job
if ( jobEntry.getSpecificationMethod() == SPECIFICATION_METHOD.REPOSITORY_BY_REFERENCE
&& jobEntry.getObjectId() == null ) {
throw new IllegalStateException(
"Entry '" + jobEntry.getName() + "' uses REPOSITORY_BY_REFERENCE but has no object ID" );
} Type guard
boolean isByReferenceWithId( JobEntryInterface e ) {
return e.getSpecificationMethod() == SPECIFICATION_METHOD.REPOSITORY_BY_REFERENCE
&& e.getObjectId() != null;
} Try / catch
try {
meta = loader.getMetaForEntry( bowl, rep, metaStore, space );
} catch ( KettleException ke ) {
if ( String.valueOf( ke.getMessage() ).contains( "ReferencedTransformationIdIsNull" ) ) {
throw new JobExecutionException( "Job entry reference has no repository object ID; re-select it in Spoon", ke );
}
throw ke;
} Prevention
- Always set both specificationMethod and objectId when constructing job entries programmatically.
- After repository migrations, run an audit that resolves every by-reference entry's ObjectId in the target repo.
- Prefer REPOSITORY_BY_NAME when referencing across repositories so IDs are not required.
- Re-save jobs in Spoon after copy/paste between jobs to verify references are intact.
When it happens
Trigger: Calling getMetaForEntry (directly or via JobEntryTrans.jobMeta()/JobEntryJob.jobMeta()) when the entry's specificationMethod is REPOSITORY_BY_REFERENCE and setMetaObjectId()/the repository reference ObjectId was never set, was lost during serialization/import, or the entry was constructed programmatically without specifying an object ID.
Common situations: Building job entries in code or via a plugin without calling setObjectId; metadata imported/migrated between repositories where object IDs were not remapped; a corrupted or hand-edited job XML/kjb file whose reference node lacks an id; repository references that were valid in one repo but are meaningless (null) in another.
Related errors
- JobJob.Exception.ReferencedTransformationIdIsNull
- Could not execute specified in a repository since we're not…
- ERROR_0002_Cannot_Load_Job_From_Repository
- JobEntryCheckFilesLocked.UnableToLoadFromRepo
- JobEntryCheckFilesLocked.UnableToSaveToRepo
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/66b424f8555d34ea.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/base/MetaFileLoaderImpl.java:244
if ( theMeta == null ) {
if ( isTransMeta() ) {
theMeta = rep == null
? (T) new TransMeta( bowl, metaPath, metaStore, null, true, jobEntryBase.getParentVariableSpace(),
null )
: getMetaFromRepository( bowl, rep, r, metaPath, tmpSpace );
} else {
theMeta = getMetaFromRepository( bowl, rep, r, metaPath, tmpSpace );
}
if ( theMeta != null ) {
idContainer[ 0 ] = metaPath;
}
}
}
break;
case REPOSITORY_BY_REFERENCE:
if ( metaObjectId == null ) {
if ( isTransMeta() ) {
throw new KettleException( BaseMessages.getString( persistentClass,
"JobTrans.Exception.ReferencedTransformationIdIsNull" ) );
} else {
throw new KettleException( BaseMessages.getString( persistentClass,
"JobJob.Exception.ReferencedTransformationIdIsNull" ) );
}
}
if ( rep != null ) {
theMeta = attemptCacheRead( metaObjectId.toString() ); //try to get from the cache first
if ( theMeta == null ) {
// Load the last revision
if ( isTransMeta() ) {
theMeta = (T) rep.loadTransformation( metaObjectId, null );
} else {
theMeta = (T) rep.loadJob( metaObjectId, null );
}
idContainer[ 0 ] = metaObjectId.toString();
}View on GitHub (pinned to f3058517a1)