pentaho/pentaho-kettle · error · KettleException

Unable to get lock for object with id

Error message

Unable to get lock for object with id [${id}]

What it means

UnifiedRepositoryLockService.getLockById fetches the RepositoryFile by ID and extracts its lock information. Any exception from the underlying repository call (file not found, access denied, connectivity) is wrapped in this KettleException. It means the lock state for the given object could not be determined or obtained.

Solutions

  1. Verify the ObjectId refers to an existing repository file (check the wrapped cause via getCause()).
  2. Re-fetch the object to get a fresh ObjectId if the repository was re-imported or the file re-created.
  3. Check the user has read access to the file in question.
  4. Check server connectivity; if the cause is a network/auth error, reconnect and retry.

Example fix

// before
RepositoryLock lock = lockService.getTransformationLock( transMeta.getObjectId() ); // may throw
// after
try {
  RepositoryLock lock = lockService.getTransformationLock( transMeta.getObjectId() );
} catch ( KettleException e ) {
  if ( pur.getFileById( transMeta.getObjectId().getId() ) == null ) {
    log.logBasic( "Object no longer exists; skipping lock check" );
  } else {
    throw e;
  }
}
Defensive patterns

Strategy: try-catch

Validate before calling

boolean lockable( UnifiedRepositoryConnection pur, ObjectId id ) {
  try { return pur.getFileById( id.getId() ) != null; } catch ( Exception e ) { return false; }
}

Try / catch

try {
  RepositoryLock lock = lockService.getJobLock( jobId );
} catch ( KettleException e ) {
  logError( "Lock lookup failed for id " + jobId + ": " + e.getCause() );
  // fall back to treating object as unlocked only if cause is not-found
}

Prevention

When it happens

Trigger: Calling lockJob, getJobLock, lockTransformation, or getTransformationLock with an ObjectId that does not exist in the repository, or when pur.getFileById fails for any reason (permissions, network, server error).

Common situations: Checking locks for objects deleted by another user, stale IDs from a previous repository instance, network/server outages during lock checks, or insufficient read permissions on the file.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — 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/c8a4f4b9e00fc1d4. Report an issue: GitHub.

Appendix: source

Thrown at plugins/pur/core/src/main/java/org/pentaho/di/repository/pur/UnifiedRepositoryLockService.java:49

  protected void lockFileById( final ObjectId id, final String message ) throws KettleException {
    pur.lockFile( id.getId(), message );
  }

  public RepositoryLock getLock( final RepositoryFile file ) throws KettleException {
    if ( file.isLocked() ) {
      return new RepositoryLock( new StringObjectId( file.getId().toString() ), file.getLockMessage(), file
          .getLockOwner(), file.getLockOwner(), file.getLockDate() );
    } else {
      return null;
    }
  }

  protected RepositoryLock getLockById( final ObjectId id ) throws KettleException {
    try {
      RepositoryFile file = pur.getFileById( id.getId() );
      return getLock( file );
    } catch ( Exception e ) {
      throw new KettleException( "Unable to get lock for object with id [" + id + "]", e );
    }
  }

  protected void unlockFileById( ObjectId id ) throws KettleException {
    pur.unlockFile( id.getId() );
  }

  @Override
  public RepositoryLock lockJob( final ObjectId idJob, final String message ) throws KettleException {
    lockFileById( idJob, message );
    return getLockById( idJob );
  }

  @Override
  public void unlockJob( ObjectId idJob ) throws KettleException {
    unlockFileById( idJob );
  }

View on GitHub (pinned to f3058517a1)