ruby-concurrency/concurrent-ruby · error · NameError

no member '#{member}' in struct

Error message

no member '#{member}' in struct

What it means

When MutableStruct#[]= receives a non-Integer member name, it dispatches via send("#{member}=") ; if no such setter exists the resulting NoMethodError is rescued and re-raised as NameError "no member 'x' in struct". This gives struct member typos a clear, Ruby-Struct-like error instead of a raw NoMethodError backtrace.

Source

Thrown at lib/concurrent-ruby/concurrent/mutable_struct.rb:196

    #   @param [Symbol, String, Integer] member the string or symbol name of the member
    #     for which to obtain the value or the member's index
    #
    #   @return [Object] the value of the given struct member or the member at the given index.
    #
    #   @raise [NameError] if the name does not exist
    #   @raise [IndexError] if the index is out of range.
    def []=(member, value)
      if member.is_a? Integer
        length = synchronize { @values.length }
        if member >= length
          raise IndexError.new("offset #{member} too large for struct(size:#{length})")
        end
        synchronize { @values[member] = value }
      else
        send("#{member}=", value)
      end
    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)

View on GitHub (pinned to 0b88d5ff75)

Solutions

  1. Check membership first: struct.class.members.include?(member.to_sym)
  2. Fix the typo — compare against Klass.members output in a console
  3. When mapping external keys, filter them through members before writing, or define the struct from the actual key set

Example fix

# before
point[:z] = 1

# after
point[:x2] = 1 if point.class.members.include?(:x2)
# or simply fix the name:
point[:x] = 1
Defensive patterns

Strategy: type-guard

Validate before calling

member = member.to_sym
raise NameError, "unknown member #{member}; valid: #{struct.class.members.join(', ')}" unless struct.class.members.include?(member)
struct[member] = value

Type guard

->(struct, m) { struct.class.members.include?(m.to_sym) }

Try / catch

begin
  struct[member] = value
rescue NameError => e
  raise FieldError, "#{e.message} (defined: #{struct.class.members.join(', ')})"
end

Prevention

When it happens

Trigger: point[:z] = 1 on a struct defined with only :x, :y; string member with a typo: struct['nmae'] = v; member names sourced dynamically (symbols from JSON keys) that don't match the defined members.

Common situations: Typos in field names during refactors; mapping external hashes into structs where key sets drift between versions; renaming struct members without updating every write site.

Related errors


AI-assisted analysis of ruby-concurrency/concurrent-ruby@0b88d5ff75 (2026-08-21). Data as JSON: /api/errors/251686b6933e4aa6. Report an issue: GitHub.