{"record":{"id":"d079ff95aa044e88","repo":"apache/hadoop","slug":"outputformat-not-set-for-filteroutputformat-d079ff","errorCode":null,"errorMessage":"OutputFormat not set for FilterOutputFormat","messagePattern":"OutputFormat not set for FilterOutputFormat","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/lib/output/FilterOutputFormat.java","lineNumber":72,"sourceCode":"  throws IOException, InterruptedException {\n    return getBaseOut().getRecordWriter(context);\n  }\n\n  @Override\n  public void checkOutputSpecs(JobContext context) \n  throws IOException, InterruptedException {\n    getBaseOut().checkOutputSpecs(context);\n  }\n\n  @Override\n  public OutputCommitter getOutputCommitter(TaskAttemptContext context) \n  throws IOException, InterruptedException {\n    return getBaseOut().getOutputCommitter(context);\n  }\n\n  private OutputFormat<K,V> getBaseOut() throws IOException {\n    if (baseOut == null) {\n      throw new IOException(\"OutputFormat not set for FilterOutputFormat\");\n    }\n    return baseOut;\n  }\n  /**\n   * <code>FilterRecordWriter</code> is a convenience wrapper\n   * class that extends the {@link RecordWriter}.\n   */\n\n  public static class FilterRecordWriter<K,V> extends RecordWriter<K,V> {\n\n    protected RecordWriter<K,V> rawWriter = null;\n\n    public FilterRecordWriter() {\n      rawWriter = null;\n    }\n    \n    public FilterRecordWriter(RecordWriter<K,V> rwriter) {\n      this.rawWriter = rwriter;","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/lib/output/FilterOutputFormat.java#L54-L90","documentation":"Thrown as IOException from FilterOutputFormat.getBaseOut (FilterOutputFormat.java:72). FilterOutputFormat is a pure delegating wrapper around a base OutputFormat; every method (getRecordWriter, checkOutputSpecs, getOutputCommitter) forwards to baseOut. If the wrapper was built with the no-arg constructor and baseOut was never assigned (it is protected, so subclasses may set it), the delegation cannot proceed and this IOException is thrown.","triggerScenarios":"Subclassing FilterOutputFormat (directly, like LazyOutputFormat does) using the default constructor and never setting the protected baseOut field, then calling checkOutputSpecs/getRecordWriter/getOutputCommitter on it. Also instantiating FilterOutputFormat with new FilterOutputFormat<>() instead of new FilterOutputFormat<>(baseFormat).","commonSituations":"Custom wrapper OutputFormats (metrics, encryption, path-rewriting) whose author forgets to pass or assign the delegate; refactoring that drops the super(baseOut) call.","solutions":["Pass the delegate via the constructor: new FilterOutputFormat<>(new TextOutputFormat<>())","In subclasses, either call super(baseOut) or assign this.baseOut before the first delegating call","Add a unit test that calls checkOutputSpecs on a minimally configured job to catch the unset delegate at build time"],"exampleFix":"// before\nclass MetricsOutputFormat<K,V> extends FilterOutputFormat<K,V> {\n  public MetricsOutputFormat() {} // baseOut stays null\n}\n\n// after\nclass MetricsOutputFormat<K,V> extends FilterOutputFormat<K,V> {\n  public MetricsOutputFormat() {\n    this.baseOut = new TextOutputFormat<>(); // or lazily from conf\n  }\n}","handlingStrategy":"validation","validationCode":"// constructor invariant: never allow an unwrapped FilterOutputFormat\npublic MyFilterOutputFormat(OutputFormat<K,V> base) {\n  super(Objects.requireNonNull(base, \"baseOut must be set\"));\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use the FilterOutputFormat(baseOut) constructor, not the no-arg one","In subclasses assign this.baseOut before any delegating method can run","Unit-test checkOutputSpecs on new wrapper instances"],"tags":["hadoop","mapreduce","output-format","filter-output-format","delegate","null-delegate"],"backgroundTag":"outputformat-delegate-not-set","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}