{"record":{"id":"f63444b0a5300d23","repo":"pentaho/pentaho-kettle","slug":"stringcut-exception-fieldtypenotstring","errorCode":null,"errorMessage":"StringCut.Exception.FieldTypeNotString","messagePattern":"StringCut\\.Exception\\.FieldTypeNotString","errorType":"exception","errorClass":"KettleStepException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/steps/stringcut/StringCut.java","lineNumber":139,"sourceCode":"    if ( first ) {\n      first = false;\n      // What's the format of the output row?\n      data.outputRowMeta = getInputRowMeta().clone();\n      data.inputFieldsNr = data.outputRowMeta.size();\n      meta.getFields( getTransMeta().getBowl(), data.outputRowMeta, getStepname(), null, null, this, repository,\n        metaStore );\n\n      data.inStreamNrs = new int[meta.getFieldInStream().length];\n      for ( int i = 0; i < meta.getFieldInStream().length; i++ ) {\n        data.inStreamNrs[i] = getInputRowMeta().indexOfValue( meta.getFieldInStream()[i] );\n        if ( data.inStreamNrs[i] < 0 ) {\n          throw new KettleStepException( BaseMessages.getString( PKG, \"StringCut.Exception.FieldRequired\", meta\n            .getFieldInStream()[i] ) );\n        }\n\n        // check field type\n        if ( getInputRowMeta().getValueMeta( data.inStreamNrs[i] ).getType() != ValueMetaInterface.TYPE_STRING ) {\n          throw new KettleStepException( BaseMessages.getString(\n            PKG, \"StringCut.Exception.FieldTypeNotString\", meta.getFieldInStream()[i] ) );\n        }\n      }\n\n      data.outStreamNrs = new String[meta.getFieldInStream().length];\n      for ( int i = 0; i < meta.getFieldInStream().length; i++ ) {\n        data.outStreamNrs[i] = environmentSubstitute( meta.getFieldOutStream()[i] );\n      }\n\n      data.cutFrom = new int[meta.getFieldInStream().length];\n      data.cutTo = new int[meta.getFieldInStream().length];\n      for ( int i = 0; i < meta.getFieldInStream().length; i++ ) {\n        if ( Utils.isEmpty( environmentSubstitute( meta.getCutFrom()[i] ) ) ) {\n          data.cutFrom[i] = 0;\n        } else {\n          data.cutFrom[i] = Const.toInt( environmentSubstitute( meta.getCutFrom()[i] ), 0 );\n        }\n","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/steps/stringcut/StringCut.java#L121-L157","documentation":"StringCut throws this KettleStepException in processRow() when an input field configured for cutting exists in the row but is not of type String. String Cut only operates on String fields; numeric, date, or boolean fields cannot be substring-cut.","triggerScenarios":"At the first processed row when getInputRowMeta().getValueMeta(index).getType() != ValueMetaInterface.TYPE_STRING for one of the configured getFieldInStream() fields.","commonSituations":"Upstream step changed the field type (e.g. source column is Integer); missing a 'Field to string' / Select Values conversion before String Cut; schema drift after changing a database table.","solutions":["Insert a 'Select Values' step before String Cut to convert the field to String","Change the cut target to a field that is already String","Adjust the upstream source/query to cast the column to text","In the step dialog, re-select the field after the type fix"],"exampleFix":"// before\nString Cut on field: amount (Integer)\n// after\nSelect Values: amount -> String (meta type String, format), then String Cut on amount","handlingStrategy":"validation","validationCode":"// validate types before execution\nRowMetaInterface input = transMeta.getPrevStepFields(stepMeta);\nfor (String f : cutMeta.getFieldInStream()) {\n  int idx = input.indexOfValue(f);\n  if (idx >= 0 && input.getValueMeta(idx).getType() != ValueMetaInterface.TYPE_STRING) {\n    throw new IllegalStateException(\"Field must be String: \" + f);\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  trans.execute(null);\n  trans.waitUntilFinished();\n} catch (KettleException e) {\n  if (e.getMessage().contains(\"FieldTypeNotString\")) {\n    // insert a Select Values step converting the field to String, then re-run\n  }\n}","preventionTips":["Insert a Select Values (type conversion to String) before text-only steps","Check source schemas after database/table changes","Preview rows to confirm runtime value types, not just design-time assumptions","Document expected field types per hop in the transformation"],"tags":["row-stream","type-check","pdi","string"],"backgroundTag":"type-mismatch","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"}