pentaho/pentaho-kettle · error · RuntimeException

Unhandled metadata injection of attribute: " +…

Error message

Unhandled metadata injection of attribute: " + attr.toString() + " - " + attr.getDescription()

What it means

During CsvInputMeta metadata injection, the constructor walks all top-level StepInjectionMetaEntry attributes and throws a RuntimeException if it encounters an attribute key it does not handle. This indicates the injection metadata set is out of sync with the supported keys (e.g. a new Pentaho version added a key this code doesn't map).

Solutions

  1. Read attr.toString()/getDescription() in the message to find the unhandled key.
  2. Add a handler branch for that key in the injection constructor, or remove it from the injected entry list.
  3. Align the producing and consuming Pentaho versions so injection metadata matches supported keys.
  4. As a stopgap, filter out known-irrelevant entries before injecting.

Example fix

// before: injecting an unsupported key
entries.add(new StepInjectionMetaEntry("NEW_KEY", "value", "New attribute"));
// after: use a supported key
entries.add(new StepInjectionMetaEntry("ENCODING", "UTF-8", "The file encoding"));
Defensive patterns

Strategy: validation

Validate before calling

Set<String> supported = Set.of("ENCLOSURE","BUFFER_SIZE","FILENAME","ROW_NUM_FIELD","FORMAT","ENCODING","FIELDS","IS_ADD_RESULT");
for (StepInjectionMetaEntry e : entries) {
  if (!supported.contains(e.getKey())) throw new IllegalArgumentException("Unsupported key: " + e.getKey());
}

Try / catch

try { injector.injectStepMetadata(stepId, meta, entries); }
catch (RuntimeException e) {
  if (e.getMessage().startsWith("Unhandled metadata injection of attribute")) {
    log.error("Bad injection key: {}", e.getMessage());
  }
}

Prevention

When it happens

Trigger: Programmatic metadata injection into a CSV Input step (StepMetaInjector.injectStepMetadata) where the entry list contains a key other than the recognized ones (e.g. FORMAT, ENCODING, FIELDS), such as a newly introduced attribute key or a typo in the injected key.

Common situations: Injecting metadata generated by a different Pentaho/plugin version; custom injection code using a wrong key string; version upgrade adding NEW keys (e.g. additional flags) that the injection consumer doesn't map.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/csvinput/CsvInputMeta.java:857

          delimiter = (String) entry.getValue();
        } else if ( attr.getKey().equals( "ENCLOSURE" ) ) {
          enclosure = (String) entry.getValue();
        } else if ( attr.getKey().equals( "BUFFERSIZE" ) ) {
          bufferSize = (String) entry.getValue();
        } else if ( attr.getKey().equals( "LAZY_CONVERSION" ) ) {
          lazyConversionActive = (Boolean) entry.getValue();
        } else if ( attr.getKey().equals( "PARALLEL" ) ) {
          runningInParallel = (Boolean) entry.getValue();
        } else if ( attr.getKey().equals( "NEWLINE_POSSIBLE" ) ) {
          newlinePossibleInFields = (Boolean) entry.getValue();
        } else if ( attr.getKey().equals( "ADD_FILENAME_RESULT" ) ) {
          isaddresult = (Boolean) entry.getValue();
        } else if ( attr.getKey().equals( "FORMAT" ) ) {
          fileFormat = (String) entry.getValue();
        } else if ( attr.getKey().equals( "ENCODING" ) ) {
          encoding = (String) entry.getValue();
        } else {
          throw new RuntimeException( "Unhandled metadata injection of attribute: "
            + attr.toString() + " - " + attr.getDescription() );
        }
      } else {
        if ( attr.getKey().equals( "FIELDS" ) ) {
          // This entry contains a list of lists...
          // Each list contains a single CSV input field definition (one line in the dialog)
          //
          List<StepInjectionMetaEntry> inputFieldEntries = entry.getDetails();
          inputFields = new TextFileInputField[inputFieldEntries.size()];
          for ( int row = 0; row < inputFieldEntries.size(); row++ ) {
            StepInjectionMetaEntry inputFieldEntry = inputFieldEntries.get( row );
            TextFileInputField inputField = new TextFileInputField();

            List<StepInjectionMetaEntry> fieldAttributes = inputFieldEntry.getDetails();
            for ( int i = 0; i < fieldAttributes.size(); i++ ) {
              StepInjectionMetaEntry fieldAttribute = fieldAttributes.get( i );
              KettleAttributeInterface fieldAttr = findAttribute( fieldAttribute.getKey() );

View on GitHub (pinned to f3058517a1)