ruby-concurrency/concurrent-ruby · error · ArgumentError
wrong number of arguments (0 for 1+)
Error message
wrong number of arguments (0 for 1+)
What it means
Concurrent::MutableStruct.new is the class-factory call that defines a new mutable, thread-safe struct class from a list of member names. Calling it with zero arguments raises ArgumentError 'wrong number of arguments (0 for 1+)' because a struct with no members is not definable.
Source
Thrown at lib/concurrent-ruby/concurrent/mutable_struct.rb:213
rescue NoMethodError
raise NameError.new("no member '#{member}' in struct")
end
private
# @!visibility private
def initialize_copy(original)
synchronize do
super(original)
ns_initialize_copy
end
end
# @!macro struct_new
def self.new(*args, &block)
clazz_name = nil
if args.length == 0
raise ArgumentError.new('wrong number of arguments (0 for 1+)')
elsif args.length > 0 && args.first.is_a?(String)
clazz_name = args.shift
end
FACTORY.define_struct(clazz_name, args, &block)
end
FACTORY = Class.new(Synchronization::LockableObject) do
def define_struct(name, members, &block)
synchronize do
clazz = Synchronization::AbstractStruct.define_struct_class(MutableStruct, Synchronization::LockableObject, name, members, &block)
members.each_with_index do |member, index|
clazz.send :remove_method, member
clazz.send(:define_method, member) do
synchronize { @values[index] }
end
clazz.send(:define_method, "#{member}=") do |value|
synchronize { @values[index] = value }
endView on GitHub (pinned to 0b88d5ff75)
Solutions
- Pass at least one member: Concurrent::MutableStruct.new(:a, :b)
- Guard dynamic member lists before the call: skip struct creation or raise a domain-specific error when the list is empty
- Log the member list when it is computed from external data so empty inputs are visible
Example fix
# before members = columns.map(&:to_sym) # [] when the table is empty Klass = Concurrent::MutableStruct.new(*members) # after raise ArgumentError, 'cannot define struct with no members' if members.empty? Klass = Concurrent::MutableStruct.new(*members)
Defensive patterns
Strategy: validation
Validate before calling
raise ArgumentError, 'at least one struct member required' if members.empty? Klass = Concurrent::MutableStruct.new(*members)
Type guard
->(list) { list.is_a?(Array) && !list.empty? && list.all? { |m| m.is_a?(Symbol) || m.is_a?(String) } } Try / catch
begin
Concurrent::MutableStruct.new(*members)
rescue ArgumentError => e
raise SchemaError, "cannot define struct: #{e.message}"
end Prevention
- Guard dynamically built member lists (DB columns, JSON keys) for emptiness before generating classes
- Cache generated struct classes keyed by member list
- Distinguish the factory call (.new on MutableStruct) from instance creation in code review
When it happens
Trigger: Concurrent::MutableStruct.new with no members; Concurrent::MutableStruct.new(*fields) where fields is an empty array from a dynamic schema; splatting an options hash by mistake so the member list is lost.
Common situations: Generating struct classes from DB columns, CSV headers, or API payloads where the source can be empty; refactoring member lists into a constant that silently becomes []; confusion between defining the class (new) and instantiating it.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- wrong number of arguments (0 for 1+)
- no member '#{member}' in struct
- `min_threads` cannot be less than #{DEFAULT_MIN_POOL_SIZE}
- `min_threads` cannot be more than `max_threads`
- no block given
AI-assisted analysis of ruby-concurrency/concurrent-ruby@0b88d5ff75 (2026-08-21).
Data as JSON: /api/errors/9a8e9236981b4c49.
Report an issue: GitHub.