{"record":{"id":"c36e281c0b989871","repo":"pentaho/pentaho-kettle","slug":"tostring-couldn-t-convert-long-to-string","errorCode":null,"errorMessage":"<toString()> : couldn't convert Long to String ","messagePattern":"<toString\\(\\)> : couldn't convert Long to String ","errorType":"exception","errorClass":"KettleValueException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/pentaho/di/core/row/value/ValueMetaBase.java","lineNumber":1312,"sourceCode":"        return null;\n      } else {\n        // Return strings padded to the specified length...\n        // This is done for backward compatibility with 2.5.x\n        // We just optimized this a bit...\n        //\n        String[] emptyPaddedStrings = Const.getEmptyPaddedStrings();\n        if ( length < emptyPaddedStrings.length ) {\n          return emptyPaddedStrings[length];\n        } else {\n          return Const.rightPad( \"\", length );\n        }\n      }\n    }\n\n    try {\n      return getDecimalFormat( false ).format( integer );\n    } catch ( Exception e ) {\n      throw new KettleValueException( toString() + \" : couldn't convert Long to String \", e );\n    }\n  }\n\n  protected synchronized String convertIntegerToCompatibleString( Long integer ) throws KettleValueException {\n    if ( integer == null ) {\n      return null;\n    }\n    return Long.toString( integer );\n  }\n\n  protected synchronized Long convertStringToInteger( 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":1294,"sourceCodeEnd":1330,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/core/src/main/java/org/pentaho/di/core/row/value/ValueMetaBase.java#L1294-L1330","documentation":"Thrown by ValueMetaBase's Long/Integer-to-String conversion when getDecimalFormat(false).format(integer) throws. It wraps the cause and names the value meta, meaning the integer could not be formatted to a string under the current format mask and locale.","triggerScenarios":"Calling getString() on a TYPE_INTEGER value when DecimalFormat.format(Long) fails — invalid conversion mask pattern, incompatible mask/locale combination, or an exception raised inside the DecimalFormat.","commonSituations":"Masks containing invalid pattern characters copied from a Number field; locale changed after masks were defined; corrupted value meta metadata loaded from an old file.","solutions":["Verify the conversion mask is a valid DecimalFormat pattern for integers (e.g. '#,##0')","Clear the mask to use the default formatting if none is required","Align setConversionLocale with the mask's separators","Catch KettleValueException and fall back to String.valueOf(long)"],"exampleFix":"// before\nvalueMeta.setConversionMask(\"#,##0.00E0;;\"); // invalid for Integer\n// after\nvalueMeta.setConversionMask(\"#,##0\");","handlingStrategy":"try-catch","validationCode":"static boolean isValidIntegerMask(String mask) {\n  try { new java.text.DecimalFormat(mask); return true; }\n  catch (IllegalArgumentException e) { return false; }\n}","typeGuard":null,"tryCatchPattern":"try {\n  String s = valueMeta.getString(longObject);\n} catch (KettleValueException e) {\n  log.error(\"Long->String format failed: \" + e.getMessage(), e);\n  return String.valueOf(longObject);\n}","preventionTips":["Use integer-appropriate masks like '#,##0' (no decimal sections)","Clear the conversion mask when default formatting is acceptable","Keep mask and ConversionLocale consistent","Test formatting after loading metadata from older files"],"tags":["integer","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"}