{"record":{"id":"a1c7631c4d72f6d2","repo":"pentaho/pentaho-kettle","slug":"tostring-couldn-t-convert-string-to-number","errorCode":null,"errorMessage":"<toString()> : couldn't convert String to number ","messagePattern":"<toString\\(\\)> : couldn't convert String to number ","errorType":"exception","errorClass":"KettleValueException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/pentaho/di/core/row/value/ValueMetaBase.java","lineNumber":1038,"sourceCode":"      DecimalFormat format = getDecimalFormat( false );\n      Number number;\n      if ( lenientStringToNumber ) {\n        number = format.parse( string );\n      } else {\n        ParsePosition parsePosition = new ParsePosition( 0 );\n        number = format.parse( string, parsePosition );\n\n        if ( parsePosition.getIndex() < string.length() ) {\n          throw new KettleValueException( toString()\n              + \" : couldn't convert String to number with \" + ( ( getFormatMask() == null ) ? \"empty format\" : \"format [\" + getFormatMask() + \"]\" ) +  \": unexpected character found at position \"\n              + ( parsePosition.getErrorIndex() + 1 ) + \" for value [\" + string + \"]\" );\n        }\n\n      }\n\n      return new Double( number.doubleValue() );\n    } catch ( Exception e ) {\n      throw new KettleValueException( toString() + \" : couldn't convert String to number \", e );\n    }\n  }\n\n  @Override\n  public synchronized SimpleDateFormat getDateFormat() {\n    return getDateFormat( getType() );\n  }\n\n  private synchronized SimpleDateFormat getDateFormat( int valueMetaType ) {\n    // If we have a Date that is represented as a String\n    // In that case we can set the format of the original Date on the String\n    // value metadata in the form of a conversion metadata object.\n    // That way, we can always convert from Date to String and back without a\n    // problem, no matter how complex the format was.\n    // As such, we should return the date SimpleDateFormat of the conversion\n    // metadata.\n    //\n    if ( conversionMetadata != null ) {","sourceCodeStart":1020,"sourceCodeEnd":1056,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/core/src/main/java/org/pentaho/di/core/row/value/ValueMetaBase.java#L1020-L1056","documentation":"Generic wrapper thrown by ValueMetaBase.convertStringToNumber when any exception occurs during string-to-Number conversion outside the specific 'unexpected character' case — e.g. ParseException from DecimalFormat.parse, null format, or numeric overflow while constructing the Double. The message names the value meta.","triggerScenarios":"Calling getNumber()/convertStringToNumber() where getDecimalFormat throws (invalid mask for the locale), the string is unparseable and hits the catch-all, or an internal error occurs before returning the Double.","commonSituations":"Conversion masks incompatible with the configured locale; strings like '--5' or completely non-numeric garbage; regional settings mismatch between data source and transformation.","solutions":["Validate/clean the input string is numeric before conversion","Fix the conversion mask / locale pairing with setConversionMask and setConversionLocale","Log the wrapped cause exception (getCause()) to identify the concrete failure","Catch KettleValueException and route bad rows to an error handling stream"],"exampleFix":"// before\nvalueMeta.setConversionMask(\"0.00\"); // data uses ',' decimal separator, locale uses '.'\n// after\nvalueMeta.setConversionMask(\"0,00\");\nvalueMeta.setConversionLocale(new Locale(\"de\", \"DE\"));","handlingStrategy":"try-catch","validationCode":"static boolean isNumeric(String s) {\n  return s != null && s.trim().matches(\"[+-]?(\\\\d+([.,]\\\\d+)?|[.,]\\\\d+)\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  Number n = valueMeta.getNumber(raw);\n} catch (KettleValueException e) {\n  Throwable cause = e.getCause(); // real parse error\n  log.error(\"String->Number failed for '\" + raw + \"': \" + cause, cause);\n  return null;\n}","preventionTips":["Inspect getCause() to find the concrete parse failure","Set conversion mask AND locale together so they agree","Clean upstream data (strip symbols, normalize separators) at ingestion","Use row-level error handling rather than failing whole transformations"],"tags":["number","parsing","kettle","conversion"],"backgroundTag":"invalid-argument-format","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"}