{"record":{"id":"b9a1d00c09d6788f","repo":"apache/druid","slug":"frame-allocator-is-not-available-the-output-chann","errorCode":null,"errorMessage":"Frame allocator is not available. The output channel might be marked as read-only, hence memory allocator is not required.","messagePattern":"Frame allocator is not available\\. The output channel might be marked as read-only, hence memory allocator is not required\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/frame/processor/PartitionedOutputChannel.java","lineNumber":105,"sourceCode":"   */\n  public synchronized WritableFrameChannel getWritableChannel()\n  {\n    if (writableChannel == null) {\n      throw new ISE(\"Writable channel is not available. The output channel might be marked as read-only,\"\n                    + \" hence no writes are allowed.\");\n    } else {\n      return writableChannel;\n    }\n  }\n\n  /**\n   * Returns the memory allocator for the writable channel. The producer uses this to generate frames for the channel.\n   * Throws ISE if the output channel is read only.\n   */\n  public synchronized MemoryAllocator getFrameMemoryAllocator()\n  {\n    if (frameMemoryAllocator == null) {\n      throw new ISE(\"Frame allocator is not available. The output channel might be marked as read-only,\"\n                    + \" hence memory allocator is not required.\");\n    } else {\n      return frameMemoryAllocator;\n    }\n  }\n\n  /**\n   * Returns the partitioned readable channel supplier of this pair. The consumer reads from this channel.\n   */\n  public synchronized Supplier<PartitionedReadableFrameChannel> getReadableChannelSupplier()\n  {\n    return readableChannelSupplier;\n  }\n\n  public synchronized PartitionedOutputChannel mapWritableChannel(final Function<WritableFrameChannel, WritableFrameChannel> mapFn)\n  {\n    if (writableChannel == null) {\n      return this;","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/frame/processor/PartitionedOutputChannel.java#L87-L123","documentation":"PartitionedOutputChannel.getFrameMemoryAllocator() returns the MemoryAllocator used by producers to allocate frames for writing. For read-only channels no allocator is stored (null), so calling this getter throws ISE: a read-only consumer never needs an allocator, so requesting one indicates the caller is mistakenly treating a read-only channel as writable.","triggerScenarios":"Calling getFrameMemoryAllocator() on a PartitionedOutputChannel created with readOnly=true, e.g. in runMerger wiring or openPartitionedChannel when the channel was constructed read-only.","commonSituations":"Stage code that unconditionally requests an allocator for every output; tests that build read-only channels then exercise producer paths; refactors flipping readOnly without auditing allocator usage.","solutions":["Construct the channel with readOnly=false when producers need to allocate and write frames.","Only request the allocator on the producer/writable side; pass null or skip allocation for read-only consumers.","Guard with a readOnly check before fetching the allocator and use an alternate code path for read-only channels."],"exampleFix":"// before\nMemoryAllocator allocator = outputChannel.getFrameMemoryAllocator();\n// after\nMemoryAllocator allocator = outputChannel.isReadOnly() ? null : outputChannel.getFrameMemoryAllocator();","handlingStrategy":"try-catch","validationCode":"if (outputChannel.isReadOnly()) {\n  // no allocator needed on the read-only path\n  return;\n}","typeGuard":"boolean needsAllocator(PartitionedOutputChannel ch) { return !ch.isReadOnly(); }","tryCatchPattern":"try {\n  MemoryAllocator a = outputChannel.getFrameMemoryAllocator();\n} catch (IllegalStateException e) {\n  // use a null allocator path for read-only consumers\n}","preventionTips":["Only request allocators on the writable/producer side.","Create channels readOnly=false when frames will be written.","Pass allocator availability through explicit parameters instead of pulling from possibly-read-only channels."],"tags":["java","illegal-state","memory-allocation"],"backgroundTag":"invalid-state-transition","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}