{"record":{"id":"c050ab44dab71567","repo":"pentaho/pentaho-kettle","slug":"jobentrysetvariables-error-unablesetvariableparentjob","errorCode":null,"errorMessage":"JobEntrySetVariables.Error.UnableSetVariableParentJob","messagePattern":"JobEntrySetVariables\\.Error\\.UnableSetVariableParentJob","errorType":"exception","errorClass":"KettleJobException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/job/entries/setvariables/JobEntrySetVariables.java","lineNumber":342,"sourceCode":"              }\n              parentJob.setVariable( varname, value );\n\n            } else {\n              throw new KettleJobException( BaseMessages.getString(\n                PKG, \"JobEntrySetVariables.Error.UnableSetVariableCurrentJob\", varname ) );\n            }\n            break;\n\n          case VARIABLE_TYPE_PARENT_JOB:\n            setVariable( varname, value );\n\n            if ( parentJob != null ) {\n              parentJob.setVariable( varname, value );\n              Job gpJob = parentJob.getParentJob();\n              if ( gpJob != null ) {\n                gpJob.setVariable( varname, value );\n              } else {\n                throw new KettleJobException( BaseMessages.getString(\n                  PKG, \"JobEntrySetVariables.Error.UnableSetVariableParentJob\", varname ) );\n              }\n            } else {\n              throw new KettleJobException( BaseMessages.getString(\n                PKG, \"JobEntrySetVariables.Error.UnableSetVariableCurrentJob\", varname ) );\n            }\n            break;\n\n          default:\n            break;\n        }\n\n        // ok we can process this line\n        if ( log.isDebug() ) {\n          logDebug( BaseMessages.getString( PKG, \"JobEntrySetVariables.Log.SetVariableToValue\", varname, value ) );\n        }\n      }\n    } catch ( Exception e ) {","sourceCodeStart":324,"sourceCodeEnd":360,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/job/entries/setvariables/JobEntrySetVariables.java#L324-L360","documentation":"This KettleJobException is thrown in execute() for the 'grand-parent job' variable scope (VARIABLE_TYPE_GRAND_PARENT_JOB): the variable was set on the parent job, but the parent job itself has no parent Job, so the requested scope cannot be honored. The message names the variable that could not be set at the grand-parent level.","triggerScenarios":"Variable type set to 'Valid in the grand-parent job' while the executing job is only nested one level deep (parentJob.getParentJob() == null) - i.e. there is no grand-parent to receive the variable.","commonSituations":"Job nesting changed (a sub-job was promoted to run directly under the root job, removing the grand-parent level); someone set the wrong scope in the dialog; reusing a copied entry that assumed deeper nesting.","solutions":["Change the variable scope to 'Valid in the parent job' (or root job) to match the actual nesting depth","Nest the job one level deeper so a grand-parent Job exists","Refactor to pass the value via result rows/parameters instead of relying on grand-parent scope"],"exampleFix":"// before\n// Variable scope: 'Valid in the grand-parent job' in a job nested only 1 level\n// after\n// Variable scope: 'Valid in the parent job'","handlingStrategy":"validation","validationCode":"// confirm the job actually has a grand-parent before grand-parent scope\nJob parent = job.getParentJob();\nif (\"GRAND_PARENT_JOB\".equals(scope) && (parent == null || parent.getParentJob() == null)) {\n  throw new IllegalStateException(\"Grand-parent variable scope requires 2 levels of job nesting\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  result = jobEntry.execute(result, nr);\n} catch (KettleJobException e) {\n  if (e.getMessage().contains(\"UnableSetVariableParentJob\")) {\n    logError(\"No grand-parent job exists; adjust the variable scope to parent job\");\n  }\n}","preventionTips":["Match variable scope to actual nesting depth; review after restructuring jobs","Prefer parent-job scope unless a grand-parent is guaranteed","Pass values across levels via result rows/parameters instead of deep scopes","Document expected job nesting when reusing sub-jobs"],"tags":["pdi","variables","scope"],"backgroundTag":"invalid-state-transition","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}