ruby-concurrency/concurrent-ruby · error · ArgumentError
cannot enqueue nil
Error message
cannot enqueue nil
What it means
This is the JRuby (java.util.PriorityQueue-backed) engine behind Concurrent::PriorityQueue. The heap uses nil as its sentinel for 'queue empty' (pop returns nil when nothing is dequeued), so a nil item would make a real entry indistinguishable from emptiness — push therefore rejects nil with ArgumentError.
Source
Thrown at lib/concurrent-ruby/concurrent/collection/java_non_concurrent_priority_queue.rb:69
@queue.size
end
alias_method :size, :length
# @!macro priority_queue_method_peek
def peek
@queue.peek
end
# @!macro priority_queue_method_pop
def pop
@queue.poll
end
alias_method :deq, :pop
alias_method :shift, :pop
# @!macro priority_queue_method_push
def push(item)
raise ArgumentError.new('cannot enqueue nil') if item.nil?
@queue.add(item)
end
alias_method :<<, :push
alias_method :enq, :push
# @!macro priority_queue_method_from_list
def self.from_list(list, opts = {})
queue = new(opts)
list.each{|item| queue << item }
queue
end
end
end
end
end
View on GitHub (pinned to 0b88d5ff75)
Solutions
- Filter nils before enqueueing: `items.compact.each { |i| queue << i }`.
- Use fetch with an explicit default instead of nil-producing lookups: `queue << config.fetch(:retry_after, DEFAULT)`.
- Represent 'no value' with a sentinel object that implements <=> rather than nil.
- Wrap items in a Struct carrying priority plus payload so nil payloads become legal values inside the wrapper.
Example fix
// before queue << config[:retry_after] # nil when key missing -> ArgumentError // after queue << config.fetch(:retry_after, DEFAULT_RETRY_AFTER)
Defensive patterns
Strategy: validation
Validate before calling
queue << item unless item.nil?
Type guard
def enqueueable?(item) !item.nil? && item.respond_to?(:<=>) end
Try / catch
begin
queue << item
rescue ArgumentError => e
raise unless e.message == 'cannot enqueue nil'
logger.warn('skipped nil task')
end Prevention
- Call #compact on source arrays before bulk enqueue.
- Use hash.fetch with a default instead of hash[] for values going into the queue.
- Items must also be mutually comparable (respond to <=>); check that alongside non-nilness.
When it happens
Trigger: `queue.push(nil)`, `queue << nil`, or `queue.enq(nil)`; enqueueing `hash[key]` for a missing key; building the queue from a list containing nils (`from_list([1, nil, 2])` pushes each item, including the nil).
Common situations: Nulls from databases, config, or JSON parsed into scheduling queues; optional fields that end up nil; forgetting #compact on input arrays; using nil as a 'lowest priority' marker.
Related errors
- cannot enqueue nil
- Could not initialize intrinsics
- Could not initialize intrinsics
- unbuffered channels cannot have a capacity
- capacity must be at least 1 for this buffer type
AI-assisted analysis of ruby-concurrency/concurrent-ruby@0b88d5ff75 (2026-08-21).
Data as JSON: /api/errors/262c971378c01df1.
Report an issue: GitHub.