{"record":{"id":"b00b97396d52d455","repo":"pentaho/pentaho-kettle","slug":"error-retrieving-badfile-string","errorCode":null,"errorMessage":"Error retrieving badfile string","messagePattern":"Error retrieving badfile string","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"plugins/oracle-bulk-loader/impl/src/main/java/org/pentaho/di/trans/steps/orabulkloader/OraBulkLoader.java","lineNumber":402,"sourceCode":"\n        sb.append( \" log=\\'\" );\n        sb.append( getFilename( fileObject ) );\n        sb.append( \"\\'\" );\n      } catch ( KettleFileException ex ) {\n        throw new KettleException( \"Error retrieving logfile string\", ex );\n      }\n    }\n\n    if ( meta.getBadFile() != null ) {\n      try {\n        FileObject fileObject =\n          getFileObject( meta.getBadFile(), getTransMeta() );\n\n        sb.append( \" bad=\\'\" );\n        sb.append( getFilename( fileObject ) );\n        sb.append( \"\\'\" );\n      } catch ( KettleFileException ex ) {\n        throw new KettleException( \"Error retrieving badfile string\", ex );\n      }\n    }\n\n    if ( meta.getDiscardFile() != null ) {\n      try {\n        FileObject fileObject =\n          getFileObject( meta.getDiscardFile(), getTransMeta() );\n\n        sb.append( \" discard=\\'\" );\n        sb.append( getFilename( fileObject ) );\n        sb.append( \"\\'\" );\n      } catch ( KettleFileException ex ) {\n        throw new KettleException( \"Error retrieving discardfile string\", ex );\n      }\n    }\n\n    DatabaseMeta dm = meta.getDatabaseMeta();\n    if ( dm != null ) {","sourceCodeStart":384,"sourceCodeEnd":420,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/plugins/oracle-bulk-loader/impl/src/main/java/org/pentaho/di/trans/steps/orabulkloader/OraBulkLoader.java#L384-L420","documentation":"When a bad (rejected-rows) file is configured, createCommandLine resolves it via VFS and appends bad='<path>'. A KettleFileException while resolving or getting the filename is wrapped in this KettleException.","triggerScenarios":"meta.getBadFile() is non-null but getFileObject(meta.getBadFile(), transMeta) or getFilename throws during createCommandLine (execute).","commonSituations":"Bad file path contains an unresolvable variable; directory missing or read-only; invalid VFS URL; relative path resolved against an unexpected working directory on an agent node.","solutions":["Correct the bad file path in the step dialog to an absolute, writable location.","Resolve/define environment variables used in the path.","Create the target directory and grant write permissions to the runtime user.","Clear the bad file field if rejected-row capture is not required."],"exampleFix":"// before\nbad file = ${BAD_DIR}/load.bad\n// after\nbad file = /tmp/orabulk/load.bad","handlingStrategy":"validation","validationCode":"// Java: pre-check optional bad file path\nString bad = meta.getBadFile();\nif (bad != null) {\n  String resolved = transMeta.environmentSubstitute(bad);\n  File dir = new File(resolved).getAbsoluteFile().getParentFile();\n  if (!dir.isDirectory() || !dir.canWrite()) {\n    throw new IllegalStateException(\"Bad-file directory missing/unwritable: \" + dir);\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  trans.execute(null);\n} catch (KettleException e) {\n  if (String.valueOf(e.getMessage()).contains(\"Error retrieving badfile\")) {\n    // fix or clear the bad file field\n  }\n}","preventionTips":["Point bad/discard/log files to a dedicated writable scratch directory.","Resolve environment variables in paths before runtime.","Clear fields you do not use instead of leaving dummy values."],"tags":["kettle","oracle","badfile","path-resolution"],"backgroundTag":"file-not-found","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"}