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

  1. 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.
  2. 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).
  3. 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.
  4. 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

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


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)