{"record":{"id":"0a11c31fcccac4a8","repo":"pentaho/pentaho-kettle","slug":"streamlookup-exception-unabletofindfield","errorCode":null,"errorMessage":"StreamLookup.Exception.UnableToFindField","messagePattern":"StreamLookup\\.Exception\\.UnableToFindField","errorType":"exception","errorClass":"KettleStepException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/steps/streamlookup/StreamLookup.java","lineNumber":167,"sourceCode":"    while ( rowData != null ) {\n      if ( log.isRowLevel() ) {\n        logRowlevel( BaseMessages.getString( PKG, \"StreamLookup.Log.ReadLookupRow\" )\n          + rowSet.getRowMeta().getString( rowData ) );\n      }\n\n      if ( firstRun ) {\n        firstRun = false;\n        data.hasLookupRows = true;\n\n        data.infoMeta = rowSet.getRowMeta().clone();\n        RowMetaInterface cacheKeyMeta = new RowMeta();\n        RowMetaInterface cacheValueMeta = new RowMeta();\n\n   // Look up the keys in the source rows\n        for ( int i = 0; i < meta.getKeylookup().length; i++ ) {\n          keyNrs[i] = rowSet.getRowMeta().indexOfValue( meta.getKeylookup()[i] );\n          if ( keyNrs[i] < 0 ) {\n            throw new KettleStepException( BaseMessages.getString(\n              PKG, \"StreamLookup.Exception.UnableToFindField\", meta.getKeylookup()[i] ) );\n          }\n          cacheKeyMeta.addValueMeta( rowSet.getRowMeta().getValueMeta( keyNrs[i] ) );\n        }\n       // Save the data types of the keys to optionally convert input rows later on...\n        if ( data.keyTypes == null ) {\n          data.keyTypes = cacheKeyMeta.clone();\n        }\n\n        // Cache keys are stored as normal types, not binary\n        for ( int i = 0; i < keyNrs.length; i++ ) {\n          cacheKeyMeta.getValueMeta( i ).setStorageType( ValueMetaInterface.STORAGE_TYPE_NORMAL );\n        }\n\n       for ( int v = 0; v < meta.getValue().length; v++ ) {\n          valueNrs[v] = rowSet.getRowMeta().indexOfValue( meta.getValue()[v] );\n          if ( valueNrs[v] < 0 ) {\n            throw new KettleStepException( BaseMessages.getString(","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/steps/streamlookup/StreamLookup.java#L149-L185","documentation":"StreamLookup throws this while reading the lookup stream when a configured key lookup field cannot be found in the incoming lookup row metadata. indexOfValue() returns -1, meaning the field name in the step's 'key lookup' setting does not exist in the source (lookup) stream. It aborts the step with KettleStepException naming the missing field.","triggerScenarios":"readLookupValues (via processRow) calls rowSet.getRowMeta().indexOfValue(meta.getKeylookup()[i]) and gets -1 because a key field in the step metadata is absent from the lookup stream's row structure.","commonSituations":"Upstream step was renamed/deleted a field after the StreamLookup step was configured; hop wiring changed so a different stream feeds the lookup input; typo in field name in transformation XML; transformation copied between environments with different upstream logic.","solutions":["Open the StreamLookup step dialog and re-select the key lookup fields so they match fields actually present on the lookup (info/source) input stream","Fix the upstream step so it emits the expected key field (check Rename Field/Delete/Select Values steps)","Re-hop the correct stream to the lookup input of the StreamLookup step","Edit the transformation XML/ktr to correct the keylookup field name typo"],"exampleFix":"// before (transformation XML)\n<key_lookup>cust_id</key_lookup>\n// after (match actual upstream field)\n<key_lookup>customerID</key_lookup>","handlingStrategy":"validation","validationCode":"// Before running the transformation, validate keys exist on the lookup stream:\nfor (String key : meta.getKeylookup()) {\n  if (lookupRowMeta.indexOfValue(key) < 0)\n    throw new IllegalStateException(\"Lookup stream missing key field: \" + key);\n}","typeGuard":"boolean lookupHasField(RowMetaInterface rowMeta, String field) {\n  return rowMeta != null && rowMeta.indexOfValue(field) >= 0;\n}","tryCatchPattern":"try {\n  step.processRow();\n} catch (KettleStepException e) {\n  if (e.getMessage().contains(\"UnableToFindField\")) { /* reconfigure field mapping */ }\n  throw e;\n}","preventionTips":["Always click 'Get lookup fields' in the step dialog after changing upstream steps","Add an 'Assert Fields' / 'Field exists in stream?' check before the lookup","Review field renames in Select Values / Rename steps near the lookup","Use version control on .ktr files so field-mapping drift is visible in diffs"],"tags":["kettle","pdi","stream-lookup","field-not-found"],"backgroundTag":"record-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"}