{"record":{"id":"03d490e42b2a285f","repo":"apache/hadoop","slug":"record-writer-not-set-for-filterrecordwriter-03d490","errorCode":null,"errorMessage":"Record Writer not set for FilterRecordWriter","messagePattern":"Record Writer not set for FilterRecordWriter","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":106,"sourceCode":"    \n    public FilterRecordWriter(RecordWriter<K,V> rwriter) {\n      this.rawWriter = rwriter;\n    }\n    \n    @Override\n    public void write(K key, V value) throws IOException, InterruptedException {\n      getRawWriter().write(key, value);\n    }\n\n    @Override\n    public void close(TaskAttemptContext context) \n    throws IOException, InterruptedException {\n      getRawWriter().close(context);\n    }\n    \n    private RecordWriter<K,V> getRawWriter() throws IOException {\n      if (rawWriter == null) {\n        throw new IOException(\"Record Writer not set for FilterRecordWriter\");\n      }\n      return rawWriter;\n    }\n  }\n}\n","sourceCodeStart":88,"sourceCodeEnd":112,"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#L88-L112","documentation":"Thrown as IOException from FilterRecordWriter.getRawWriter (FilterOutputFormat.java:106). FilterRecordWriter delegates write() and close() to a raw RecordWriter; if it was created with the no-arg constructor and rawWriter was never set (the field is protected), the first write() or close() call hits this guard. Note that LazyOutputFormat's internal LazyRecordWriter overrides write/close and assigns rawWriter itself, so this error comes from custom subclasses or direct misuse of FilterRecordWriter.","triggerScenarios":"Extending FilterRecordWriter with the default constructor, overriding neither the assignment of rawWriter nor write/close, then calling write(key, value) or close(context). Also new FilterRecordWriter<>() used directly as a RecordWriter without wrapping anything.","commonSituations":"Custom writer wrappers (counting, validating, transforming) where the author forgets super(rawWriter) in the constructor or to lazily create the writer in an overridden write().","solutions":["Initialize the delegate via the constructor: super(actualWriter)","Or assign the protected rawWriter field lazily before first use (the LazyRecordWriter pattern: create on first write)","Override write()/close() only when you also guarantee rawWriter is non-null by the time they run"],"exampleFix":"// before\nclass CountingWriter<K,V> extends FilterOutputFormat.FilterRecordWriter<K,V> {\n  public CountingWriter() {} // rawWriter never set -> write() throws\n}\n\n// after\nclass CountingWriter<K,V> extends FilterOutputFormat.FilterRecordWriter<K,V> {\n  public CountingWriter(RecordWriter<K,V> inner) {\n    super(inner);\n  }\n}","handlingStrategy":"validation","validationCode":"// enforce the delegate at construction\nclass MyWriter<K,V> extends FilterOutputFormat.FilterRecordWriter<K,V> {\n  MyWriter(RecordWriter<K,V> inner) { super(Objects.requireNonNull(inner)); }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always call super(rawWriter) when subclassing FilterRecordWriter","If creating the writer lazily, assign rawWriter on first write() like LazyRecordWriter does","Avoid the no-arg constructor unless you override write/close entirely"],"tags":["hadoop","mapreduce","record-writer","filter-output-format","delegate","null-delegate"],"backgroundTag":"record-writer-not-set","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}