{"record":{"id":"823d535ed6234e6d","repo":"pentaho/pentaho-kettle","slug":"kettlevalueexception-wrapping-generic-exception-while","errorCode":null,"errorMessage":"KettleValueException wrapping generic Exception while loading file content (no message)","messagePattern":"KettleValueException wrapping generic Exception while loading file content \\(no message\\)","errorType":"exception","errorClass":"org.pentaho.di.core.exception.KettleValueException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/pentaho/di/core/row/ValueDataUtil.java","lineNumber":714,"sourceCode":"\n    byte[] content = null;\n    FileObject file = null;\n    InputStream is = null;\n\n    try {\n      file = KettleVFS.getInstance( bowl ).getFileObject( dataA.toString() );\n      throwsErrorOnFileNotFound( file );\n      is = KettleVFS.getInputStream( file );\n      int fileSize = (int) file.getContent().getSize();\n      content = Const.createByteArray( fileSize );\n      is.read( content, 0, fileSize );\n    } catch ( KettleFileNotFoundException e ) {\n      if ( failIfNoFile ) {\n        throw e;\n      }\n      log.debug( e.getMessage() );\n    } catch ( Exception e ) {\n      throw new KettleValueException( e );\n    } finally {\n      IOUtils.closeQuietly( file );\n      IOUtils.closeQuietly( is );\n    }\n    return content;\n  }\n\n  public static Object minus( ValueMetaInterface metaA, Object dataA, ValueMetaInterface metaB, Object dataB ) throws KettleValueException {\n    if ( dataA == null || dataB == null ) {\n      return null;\n    }\n\n    switch ( metaA.getType() ) {\n      case ValueMetaInterface.TYPE_NUMBER:\n        return new Double( metaA.getNumber( dataA ).doubleValue() - metaB.getNumber( dataB ).doubleValue() );\n      case ValueMetaInterface.TYPE_INTEGER:\n        return new Long( metaA.getInteger( dataA ).longValue() - metaB.getInteger( dataB ).longValue() );\n      case ValueMetaInterface.TYPE_BIGNUMBER:","sourceCodeStart":696,"sourceCodeEnd":732,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/core/src/main/java/org/pentaho/di/core/row/ValueDataUtil.java#L696-L732","documentation":"The full loadFileContentInBinary deliberately rethrows KettleFileNotFoundException (honoring failIfNoFile), but any OTHER exception while reading the file (VFS IOException, closed stream, encoding errors) is wrapped in a message-less KettleValueException(e). The cause carries the real problem; the message itself is empty.","triggerScenarios":"Calling loadFileContentInBinary(bowl, metaA, dataA, failIfNoFile) where the file exists but cannot be read: VFS provider error, permission denied, stream closed, or out-of-memory on huge files.","commonSituations":"Permission-restricted files in production; VFS misconfiguration (bad scheme/auth for sftp/http files); reading files locked by another process.","solutions":["Log/print e.getCause() to get the real underlying IOException","Check file read permissions for the user running the transformation","Validate the VFS URL/scheme and credentials for remote files","Pre-check file.canRead() / exists() before the call"],"exampleFix":"// before\nObject content = ValueDataUtil.loadFileContentInBinary(bowl, metaA, dataA, true);\n// after\ntry {\n  Object content = ValueDataUtil.loadFileContentInBinary(bowl, metaA, dataA, true);\n} catch (KettleValueException e) {\n  log.error(\"File content load failed: \" + e.getCause(), e);\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":"// Java: verify readability before the call\nFileObject f = KettleVFS.getFileObject(metaA.getString(dataA));\nif (f == null || !f.exists()) throw new FileNotFoundException(...);\nif (!f.isReadable()) throw new AccessDeniedException(f.getName().getPath());","typeGuard":null,"tryCatchPattern":"try {\n  content = ValueDataUtil.loadFileContentInBinary(bowl, metaA, dataA, failIfNoFile);\n} catch (KettleValueException e) {\n  Throwable cause = e.getCause(); // the real IOException lives here\n  log.error(\"File content load failed: \" + (cause == null ? \"unknown\" : cause.getMessage()), cause);\n  throw e;\n}","preventionTips":["Always inspect getCause() — the KettleValueException message is empty","Run the transformation under a user with read access to target files","Validate VFS URLs (scheme, credentials) for remote file systems","Set failIfNoFile=false only when missing files are an expected, handled case"],"tags":["file","io","wrapped-exception","kettle"],"backgroundTag":"file-read-failed","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"}