{"record":{"id":"347a10c3f25744b9","repo":"pentaho/pentaho-kettle","slug":"tostring-couldn-t-convert-number-to-string","errorCode":null,"errorMessage":"<toString()> : couldn't convert Number to String ","messagePattern":"<toString\\(\\)> : couldn't convert Number to String ","errorType":"exception","errorClass":"KettleValueException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/pentaho/di/core/row/value/ValueMetaBase.java","lineNumber":999,"sourceCode":"        if ( length < emptyPaddedStrings.length ) {\n          return emptyPaddedStrings[length];\n        } else {\n          return Const.rightPad( \"\", length );\n        }\n      }\n    }\n\n    try {\n      DecimalFormat format = getDecimalFormat( false );\n\n      // When conversion masks are different, we must ensure the number precision is not lost\n      if ( this.conversionMask != null && storageMetadata != null\n              && !this.conversionMask.equals( storageMetadata.getConversionMask() ) ) {\n        format.setMaximumFractionDigits( 50 );\n      }\n      return format.format( number );\n    } catch ( Exception e ) {\n      throw new KettleValueException( toString() + \" : couldn't convert Number to String \", e );\n    }\n  }\n\n  protected synchronized String convertNumberToCompatibleString( Double number ) throws KettleValueException {\n    if ( number == null ) {\n      return null;\n    }\n    return Double.toString( number );\n  }\n\n  protected synchronized Double convertStringToNumber( String string ) throws KettleValueException {\n    string = Const.trimToType( string, getTrimType() ); // see if trimming needs\n    // to be performed before\n    // conversion\n\n    if ( Utils.isEmpty( string ) ) {\n      return null;\n    }","sourceCodeStart":981,"sourceCodeEnd":1017,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/core/src/main/java/org/pentaho/di/core/row/value/ValueMetaBase.java#L981-L1017","documentation":"Thrown by ValueMetaBase's Number-to-String conversion when DecimalFormat.format(number) throws for any reason. It wraps the underlying exception and names the value meta, meaning the numeric value could not be formatted with the current format mask/locale settings.","triggerScenarios":"Calling getString() on a TYPE_NUMBER value when DecimalFormat.format fails — e.g. a NaN/Infinity value with certain masks, an invalid or incompatible conversion mask, or a broken DecimalFormat created from a bad format string/locale.","commonSituations":"Conversion masks with illegal characters; formatting Double.NaN or Infinity with a decimal mask; mask mismatch between this value meta and storageMetadata triggering the 50-fraction-digit path; locale changes making the mask invalid.","solutions":["Check the conversion mask is a valid DecimalFormat pattern for the value","Handle NaN/Infinity values before conversion (substitute null or a string)","Normalize the conversion mask so it matches storageMetadata or clear it","Catch KettleValueException and fall back to String.valueOf(number)"],"exampleFix":"// before\nvalueMeta.setConversionMask(\"###,##0.00;;\"); // invalid pattern\n// after\nvalueMeta.setConversionMask(\"#,##0.00\");","handlingStrategy":"try-catch","validationCode":"static boolean isValidDecimalMask(String mask, Locale locale) {\n  try { new java.text.DecimalFormat(mask, new java.text.DecimalFormatSymbols(locale)); return true; }\n  catch (IllegalArgumentException e) { return false; }\n}","typeGuard":null,"tryCatchPattern":"try {\n  String s = valueMeta.getString(numberObject);\n} catch (KettleValueException e) {\n  log.error(\"Number format failed: \" + e.getMessage(), e);\n  return String.valueOf(numberObject); // fallback\n}","preventionTips":["Test masks with edge values (NaN, Infinity, very large fractions)","Keep conversion mask consistent between value meta and storageMetadata","Validate mask syntax with DecimalFormat before applying it","Avoid exotic masks copied between Number/Integer fields"],"tags":["number","format","decimalformat","kettle"],"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"}