pentaho/pentaho-kettle · error · KettleStepException

Unable to get value for field [ + field.getName() + ]. …

Error message

Unable to get value for field [ + field.getName() + ].  Verify that this is not a complex data type by looking at the response XML.

What it means

KettleStepException thrown while reading a mapped output field's value via vReader.getElementText() in WebService's StAX row-processing path. An XMLStreamException here usually means the element mapped to the field is a complex (nested) type or ends earlier than expected, so the reader cannot produce simple text content.

Solutions

  1. Inspect the response XML: if the mapped field is a complex type, map its leaf text elements individually instead.
  2. Enable 'pass complex data as XML' style handling or map the parent node so it is serialized as XML rather than read as text.
  3. Verify field names and namespace handling ('ignore namespace prefix') match the response.
  4. Re-fetch the operation/WSDL metadata if the service contract changed.

Example fix

// before
// output field "address" mapped to the complex <address><street>..</street></address> element
// after
// map output field "street" to the leaf element <street> which contains text
Defensive patterns

Strategy: validation

Validate before calling

// Before mapping, confirm each configured output field is a leaf (text-only) element in the response:
// e.g. check with XPath that the element has no element children:
NodeList kids = (NodeList) xpath.evaluate(field.getName() + "/*", doc, XPathConstants.NODESET);
if (kids.getLength() > 0) throw new IllegalStateException("Complex type mapped as scalar: " + field.getName());

Try / catch

try {
  // run transformation
} catch (KettleStepException e) {
  if (e.getMessage() != null && e.getMessage().contains("Verify that this is not a complex data type")) {
    // remap the offending field to its leaf child elements
  }
}

Prevention

When it happens

Trigger: During processRows with single-field/specific-field output mapping: vReader.getElementText() throws XMLStreamException because the current element has child elements (complex data type) instead of plain text.

Common situations: Developer maps a nested/complex element (e.g. an object with child elements) to a scalar output field; SOAP response structure changed so the mapped element now wraps children; namespace prefixes cause the reader to land on the wrong element.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/webservices/WebService.java:876

                } else {
                  WebServiceField field =
                    meta.getFieldOutFromWsName( vReader.getLocalName(), ignoreNamespacePrefix );
                  if ( meta.getFieldsOut().size() == 1 && field != null ) {
                    // This can be either a simple return element, or a complex type...
                    //
                    try {
                      if ( meta.isPassingInputData() ) {
                        for ( int i = 0; i < rowMeta.getValueMetaList().size(); i++ ) {
                          ValueMetaInterface valueMeta = getInputRowMeta().getValueMeta( i );
                          outputRowData[ outputIndex++ ] = valueMeta.cloneValueData( rowData[ i ] );

                        }
                      }

                      outputRowData[ outputIndex++ ] = getValue( vReader.getElementText(), field );
                      putRow( data.outputRowMeta, outputRowData );
                    } catch ( XMLStreamException e ) {
                      throw new KettleStepException( "Unable to get value for field ["
                        + field.getName()
                        + "].  Verify that this is not a complex data type by looking at the response XML.", e );
                    }
                  } else {
                    for ( WebServiceField curField : meta.getFieldsOut() ) {
                      if ( !Utils.isEmpty( curField.getName() ) ) {
                        outputRowData[ outputIndex++ ] = getValue( vReader.getElementText(), curField );
                      }
                    }
                    processing = true;
                  }
                }

              } else {
                if ( log.isRowLevel() ) {
                  logRowlevel( "vReader.getLocalName = " + vReader.getLocalName() );
                }
                if ( log.isRowLevel() ) {

View on GitHub (pinned to f3058517a1)