pentaho/pentaho-kettle · error · KettleStepException

Can't set variable [

Error message

Can't set variable [

What it means

When the variable scope is 'set on the parent job' (VARIABLE_TYPE_PARENT_JOB... parent-job variant), the step asks the transformation's parent job to store the variable. If trans.getParentJob() returns null — the transformation is not running inside a job — the variable cannot be set and a KettleStepException is thrown.

Solutions

  1. Run the transformation inside a Job (e.g. a Job entry 'Transformation') so a parent job exists
  2. Change the variable scope to 'Valid in the Java virtual machine' or 'Valid in the root job' which does not require a parent job
  3. If executed via API, wrap the Trans in an executing Job or set the variable directly on your own VariableSpace

Example fix

// before
trans.execute(null);
// after
Job job = new Job(null, jobMeta);
job.getJobMeta().addJobEntry(...transformation entry...);
job.start();
Defensive patterns

Strategy: validation

Validate before calling

if (trans.getParentJob() == null) {
  // transformation is running standalone: avoid PARENT_JOB scope
  setVariableScope(SetVariableMeta.VARIABLE_TYPE_ROOT_JOB);
}

Type guard

boolean hasParentJob(Trans trans) { return trans != null && trans.getParentJob() != null; }

Try / catch

try { trans.execute(null); } catch (KettleStepException e) { if (e.getMessage().startsWith("Can't set variable")) { /* fallback: JVM scope or wrap in a Job */ } else throw e; }

Prevention

When it happens

Trigger: Step variable type is PARENT_JOB (or GRAND_PARENT_JOB variant path) and processRow calls setValue while trans.getParentJob() == null, i.e. the transformation runs standalone or via a caller that is not a Job.

Common situations: Running a transformation directly in Spoon or via Kitchen/trans without a wrapping job; switching a Set Variable step's scope from 'Valid in the root job' to 'Valid in the parent job' while it is not executed from a job.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/0d97b900d64dad49. Report an issue: GitHub.

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/setvariable/SetVariable.java:183

      case SetVariableMeta.VARIABLE_TYPE_ROOT_JOB:
        // Comments by SB
        // VariableSpace rootJob = null;
        parentJob = trans.getParentJob();
        while ( parentJob != null ) {
          parentJob.setVariable( varname, value );
          // rootJob = parentJob;
          parentJob = parentJob.getParentJob();
        }
        break;

      case SetVariableMeta.VARIABLE_TYPE_GRAND_PARENT_JOB:
        // Set the variable in the parent job
        //
        parentJob = trans.getParentJob();
        if ( parentJob != null ) {
          parentJob.setVariable( varname, value );
        } else {
          throw new KettleStepException( "Can't set variable ["
            + varname + "] on parent job: the parent job is not available" );
        }

        // Set the variable on the grand-parent job
        //
        VariableSpace gpJob = trans.getParentJob().getParentJob();
        if ( gpJob != null ) {
          gpJob.setVariable( varname, value );
        } else {
          throw new KettleStepException( "Can't set variable ["
            + varname + "] on grand parent job: the grand parent job is not available" );
        }
        break;

      case SetVariableMeta.VARIABLE_TYPE_PARENT_JOB:
        // Set the variable in the parent job
        //
        parentJob = trans.getParentJob();

View on GitHub (pinned to f3058517a1)