{"record":{"id":"2862d5342fc4d11d","repo":"pentaho/pentaho-kettle","slug":"an-error-was-detected-in-the-step-attributes-definition-the","errorCode":null,"errorMessage":"An error was detected in the step attributes' definition: the parent was not found for attribute {0}","messagePattern":"An error was detected in the step attributes' definition: the parent was not found for attribute (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/step/BaseStepMeta.java","lineNumber":927,"sourceCode":"  protected StepInjectionMetaEntry createEntry( KettleAttributeInterface attr, Class<?> PKG ) {\n    return new StepInjectionMetaEntry( attr.getKey(), attr.getType(), BaseMessages.getString( PKG, attr\n      .getDescription() ) );\n  }\n\n  /**\n   * Describe the metadata attributes that can be injected into this step metadata object.\n   */\n  public List<StepInjectionMetaEntry> getStepInjectionMetadataEntries( Class<?> PKG ) {\n    List<StepInjectionMetaEntry> entries = new ArrayList<StepInjectionMetaEntry>();\n\n    for ( KettleAttributeInterface attr : attributes ) {\n      if ( attr.getParent() == null ) {\n        entries.add( createEntry( attr, PKG ) );\n      } else {\n        StepInjectionMetaEntry entry = createEntry( attr, PKG );\n        StepInjectionMetaEntry parentEntry = findParentEntry( entries, attr.getParent().getKey() );\n        if ( parentEntry == null ) {\n          throw new RuntimeException(\n            \"An error was detected in the step attributes' definition: the parent was not found for attribute \"\n              + attr );\n        }\n        parentEntry.getDetails().add( entry );\n      }\n    }\n\n    return entries;\n  }\n\n  /**\n   * Load step attributes.\n   *\n   * @throws KettleException the kettle exception\n   */\n  protected void loadStepAttributes() throws KettleException {\n    try ( InputStream inputStream = getClass().getResourceAsStream( STEP_ATTRIBUTES_FILE ) ) {\n      if ( inputStream != null ) {","sourceCodeStart":909,"sourceCodeEnd":945,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/step/BaseStepMeta.java#L909-L945","documentation":"Thrown by BaseStepMeta.getStepInjectionMetadataEntries when building the step injection metadata tree. Each KettleAttribute may declare a parent attribute key; if the parent's entry cannot be found among the entries already built, the attribute hierarchy is inconsistent. This is a bug in the step metadata definition, not a user configuration error.","triggerScenarios":"Calling getStepInjectionMetadataEntries() on a step meta whose KettleAttribute list references a parent key that is not present in the attributes list, or whose parent entry appears after the child in iteration order so findParentEntry() misses it.","commonSituations":"Custom step plugin developers define a KettleAttribute with a parentId that was never registered (typo in the key, parent attribute removed during refactoring, or attributes loaded from an incomplete STEP_ATTRIBUTES_FILE).","solutions":["Check the custom step's attribute definitions and ensure every parentId/key references an attribute that exists in the list before the child.","Fix typos in the parent key string or remove the stale parentId from the child attribute.","Ensure the parent attribute is registered/added before its children so findParentEntry can locate it.","If loading from a JSON step attributes file, verify the file contains the parent attribute definition."],"exampleFix":"// before\nnew KettleAttribute(\"rows_limit\", \"ROWS_LIMIT\", null, \"Row limit\", \"\", ValueMetaInterface.TYPE_INTEGER, findParent(attributes, \"row_lmit\"));\n// after\nnew KettleAttribute(\"rows_limit\", \"ROWS_LIMIT\", null, \"Row limit\", \"\", ValueMetaInterface.TYPE_INTEGER, findParent(attributes, \"row_limit\"));","handlingStrategy":"validation","validationCode":"// Validate attribute hierarchy before building injection entries\nfor (KettleAttribute attr : attributes) {\n  if (attr.getParent() != null) {\n    boolean found = attributes.stream().anyMatch(a -> a.getKey().equals(attr.getParent().getKey()));\n    if (!found) throw new IllegalStateException(\"Missing parent for attribute \" + attr.getKey());\n  }\n}","typeGuard":null,"tryCatchPattern":"try { entries = meta.getStepInjectionMetadataEntries(); } catch (RuntimeException e) { if (e.getMessage().contains(\"parent was not found\")) { log.error(\"Broken attribute hierarchy in step meta: \" + e.getMessage()); } else { throw e; } }","preventionTips":["Always register the parent attribute before its children","Extract parent key strings into constants to avoid typos","Add a unit test that builds injection metadata entries for every custom step meta"],"tags":["kettle","step-metadata","injection","parent-not-found"],"backgroundTag":"entity-not-found","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"}