{"record":{"id":"927dd6c907384177","repo":"pentaho/pentaho-kettle","slug":"unable-to-convert-a-value-to-integer-while-calculating-the","errorCode":null,"errorMessage":"Unable to convert a value to integer while calculating the partition number","messagePattern":"Unable to convert a value to integer while calculating the partition number","errorType":"exception","errorClass":"KettleStepException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/step/BaseStep.java","lineNumber":1379,"sourceCode":"  private void specialPartitioning( RowMetaInterface rowMeta, Object[] row ) throws KettleStepException {\n    if ( nextStepPartitioningMeta == null ) {\n      // Look up the partitioning of the next step.\n      // This is the case for non-clustered partitioning...\n      //\n      List<StepMeta> nextSteps = transMeta.findNextSteps( stepMeta );\n      if ( nextSteps.size() > 0 ) {\n        nextStepPartitioningMeta = nextSteps.get( 0 ).getStepPartitioningMeta();\n      }\n\n      // TODO: throw exception if we're not partitioning yet.\n      // For now it throws a NP Exception.\n    }\n\n    int partitionNr;\n    try {\n      partitionNr = nextStepPartitioningMeta.getPartition( rowMeta, row );\n    } catch ( KettleException e ) {\n      throw new KettleStepException(\n        \"Unable to convert a value to integer while calculating the partition number\", e );\n    }\n\n    RowSet selectedRowSet = null;\n\n    if ( clusteredPartitioningFirst ) {\n      clusteredPartitioningFirst = false;\n\n      // We are only running remotely if both the distribution is there AND if the distribution is actually contains\n      // something.\n      //\n      clusteredPartitioning =\n        transMeta.getSlaveStepCopyPartitionDistribution() != null\n          && !transMeta.getSlaveStepCopyPartitionDistribution().getDistribution().isEmpty();\n    }\n\n    // OK, we have a SlaveStepCopyPartitionDistribution in the transformation...\n    // We want to pre-calculate what rowset we're sending data to for which partition...","sourceCodeStart":1361,"sourceCodeEnd":1397,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/step/BaseStep.java#L1361-L1397","documentation":"BaseStep.putError/partitioning code computes the partition number for a row by calling Partitioner.getPartition(rowMeta, row), which must convert a partitioning field value to an integer. When the field value cannot be converted (KettleValueException wrapped in KettleException), BaseStep rethrows it as a KettleStepException with this message. It means the row's partitioning column holds data that is not a valid integer.","triggerScenarios":"A step is partitioned (e.g. mod partitioning) across multiple copies and the field used as the partitioning key contains a non-integer value (string text, null handling, decimal, or out-of-range number) for the current row, so getPartition() throws while converting it to int.","commonSituations":"Partitioning on a String field that contains text instead of numbers; using a field with a different type than expected after an upstream step changed metadata; partitioning on a Number field with fractional values; nulls or locale-formatted numbers.","solutions":["Point the partitioner at a field that is guaranteed Integer type (add a 'Select values' / 'Fields select' or Calculator step to convert it beforehand).","If partitioning on strings, ensure the mapping field contains only numeric strings, or switch to a partitioner that handles the type.","Clean/null-guard the data upstream: filter or default rows whose partition field is null or non-numeric.","Catch KettleStepException in a calling routine and inspect the cause (KettleValueException) to identify the offending row/field via row logging."],"exampleFix":"// before (partitioning on a string field directly)\npartitioner.setFieldName(\"order_id_text\");\n\n// after (convert to Integer before the partitioned step)\n// Add a Calculator/SelectValues step: order_id_text -> Integer order_id\npartitioner.setFieldName(\"order_id\");","handlingStrategy":"validation","validationCode":"// Java: validate partition field before putRow\nObject val = row[getFieldIndex(rowMeta, \"partitionField\")];\nif (val == null || !(val instanceof Number) ) {\n  throw new IllegalArgumentException(\"partitionField must be a numeric integer\");\n}","typeGuard":"boolean isValidPartitionValue(Object v) {\n  return v instanceof Integer || (v instanceof Number && ((Number) v).doubleValue() == Math.floor(((Number) v).doubleValue()));\n}","tryCatchPattern":"try {\n  putRow(rowMeta, row);\n} catch (KettleStepException e) {\n  if (e.getMessage().contains(\"Unable to convert a value to integer\")) {\n    logError(\"Bad partition key in row: \" + Arrays.toString(row), e);\n    // route to error handling or skip\n  } else { throw e; }\n}","preventionTips":["Always partition on Integer-typed fields","Add a value-conversion step before the partitioned step","Null-guard or filter rows with missing partition keys"],"tags":["partitioning","type-conversion","kettle"],"backgroundTag":"invalid-argument-value","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"}