pentaho/pentaho-kettle · error · KettleException
Could not execute specified in a repository since we're not…
Error message
Could not execute <friendlyMetaType> specified in a repository since we're not connected to one
What it means
The job entry says its object lives in a repository (specificationMethod = REPOSITORY_BY_REFERENCE, or by-name repo resolution reaching the load step), but the Repository handle passed to getMetaForEntry is null — the process is not connected to a repository. Kettle throws a KettleException stating it cannot execute the <transformation/job> specified in a repository without an active repository connection.
Solutions
- Connect to the repository before running: supply -rep <repoName> -user <user> -pass <password> to Kitchen/Pan, or pass a connected Repository object in the Java API.
- If the entry should not depend on a repository, change its specificationMethod to FILENAME and point it at the ktr/kjb file path.
- Verify repository login succeeded (check rep.isConnected()) before Job.execute() and fail fast with a clear message.
- For tests, mock/stub a Repository or switch the entry to REPOSITORY_BY_NAME/FILENAME modes that have non-repo fallbacks.
Example fix
// before (Java API) Job job = new Job( null, jobMeta ); // rep == null, entry is REPOSITORY_BY_REFERENCE // after KettleEnvironment.init(); RepositoriesMeta reposMeta = new RepositoriesMeta(); reposMeta.readData(); Repository rep = KettleDatabaseRepository.findRepository( reposMeta, "repo1" ); rep.connect( "admin", "admin" ); Job job = new Job( null, jobMeta, rep ); // connected repository supplied
Defensive patterns
Strategy: try-catch
Validate before calling
// fail fast before execution if the entry needs a repository
if ( jobEntry.getSpecificationMethod() == SPECIFICATION_METHOD.REPOSITORY_BY_REFERENCE
&& ( rep == null || !rep.isConnected() ) ) {
throw new IllegalStateException( "Not connected to a repository but entry requires one" );
} Type guard
boolean repositoryAvailable( Repository rep ) {
return rep != null && rep.isConnected();
} Try / catch
try {
meta = loader.getMetaForEntry( bowl, rep, metaStore, space );
} catch ( KettleException ke ) {
if ( String.valueOf( ke.getMessage() ).contains( "not connected to" ) ) {
rep = connectRepository( repoName, user, password ); // reconnect then retry once
meta = loader.getMetaForEntry( bowl, rep, metaStore, space );
} else {
throw ke;
}
} Prevention
- Always pass -rep/-user/-pass to Kitchen/Pan when running repository-defined jobs.
- Check rep.isConnected() as a precondition of job execution in schedulers.
- Handle repository login failures explicitly instead of continuing with a null Repository.
- For standalone runs, switch entries to FILENAME mode so no repository is needed.
When it happens
Trigger: Executing a job (locally, via Kitchen, Java API, or tests) where the entry's specificationMethod is REPOSITORY_BY_REFERENCE but getMetaForEntry receives rep == null — e.g. running a job metadata object outside a repository context, a failed/not-performed repository login, or passing null as the Repository argument to Job.execute/JobMeta loaders.
Common situations: Running Kitchen/Pan with a repo-defined job but without -rep/-user/-pass connection parameters; unit tests constructing JobMeta without a Repository; a KettleDatabaseRepository login that failed silently; scheduling environments where the repository connection was dropped before execution.
Related errors
- JobJob.Exception.ReferencedTransformationIdIsNull
- JobTrans.Exception.ReferencedTransformationIdIsNull
- 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/7b25e4c1de6bcf44.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/base/MetaFileLoaderImpl.java:264
} 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();
}
} else {
throw new KettleException(
"Could not execute " + friendlyMetaType + " specified in a repository since we're not connected to one" );
}
break;
default:
throw new KettleException( "The specified object location specification method '"
+ specificationMethod + "' is not yet supported in this " + friendlyMetaType + " entry." );
}
cacheMeta( idContainer[ 0 ], theMeta );
// Re-seed the internal directory variables on the returned meta from the freshly resolved tmpSpace.
// The cache may return an instance whose internal vars were last set in a different context
// (e.g. from a step loader using getVarSpaceOnlyWithRequiredParentVars, or with rep==null),
// which would otherwise leak the wrong Internal.Entry.Current.Directory into the child execution.
reseedInternalDirectoryVars( theMeta, tmpSpace );
return theMeta;
} catch ( final KettleException ke ) {
// if we get a KettleException, simply re-throw it
throw ke;View on GitHub (pinned to f3058517a1)