{"record":{"id":"028a7d7d7fd53036","repo":"ruby-concurrency/concurrent-ruby","slug":"offset-member-too-large-for-struct-size-lengt","errorCode":null,"errorMessage":"offset #{member} too large for struct(size:#{length})","messagePattern":"offset #(.+?) too large for struct\\(size:#(.+?)\\)","errorType":"exception","errorClass":"IndexError","httpStatus":null,"severity":"error","filePath":"lib/concurrent-ruby/concurrent/mutable_struct.rb","lineNumber":189,"sourceCode":"\n    # @!macro struct_set\n    #\n    #   Attribute Assignment\n    #\n    #   Sets the value of the given struct member or the member at the given index.\n    #\n    #   @param [Symbol, String, Integer] member the string or symbol name of the member\n    #     for which to obtain the value or the member's index\n    #\n    #   @return [Object] the value of the given struct member or the member at the given index.\n    #\n    #   @raise [NameError] if the name does not exist\n    #   @raise [IndexError] if the index is out of range.\n    def []=(member, value)\n      if member.is_a? Integer\n        length = synchronize { @values.length }\n        if member >= length\n          raise IndexError.new(\"offset #{member} too large for struct(size:#{length})\")\n        end\n        synchronize { @values[member] = value }\n      else\n        send(\"#{member}=\", value)\n      end\n    rescue NoMethodError\n      raise NameError.new(\"no member '#{member}' in struct\")\n    end\n\n    private\n\n    # @!visibility private\n    def initialize_copy(original)\n      synchronize do\n        super(original)\n        ns_initialize_copy\n      end\n    end","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/ruby-concurrency/concurrent-ruby/blob/0b88d5ff75f69b3740c8f0868e76f833cb2fd45d/lib/concurrent-ruby/concurrent/mutable_struct.rb#L171-L207","documentation":"MutableStruct instances store member values in a fixed-length array; #[]= with an Integer index checks it against the number of members and raises IndexError 'offset N too large for struct(size:M)' when the index is at or beyond the size. This mirrors core Ruby's Struct#[]= bounds checking.","triggerScenarios":"point[2] = 3 on a two-member struct; loops that iterate 0..count instead of 0...count-1; computing an index from external data (row/column numbers) without clamping; off-by-one after refactoring member lists.","commonSituations":"Translating CSV/DB column positions to struct indices where a wider row hits a narrower struct; loops written against an older member list; index arithmetic with interpolated user input.","solutions":["Bounds-check against size before assignment: use 0...struct.class.members.length ranges","Prefer named access: point.x = 1 or point[:x] = 1 — typos surface as NameError at the same place but are easier to spot in review","When the index comes from external data, validate and clamp or reject it at the boundary"],"exampleFix":"# before\nstruct[i] = value # i can reach struct.class.members.length\n\n# after\nif i >= 0 && i < struct.class.members.length\n  struct[i] = value\nelse\n  raise IndexError, \"index #{i} outside 0...#{struct.class.members.length}\"\nend","handlingStrategy":"type-guard","validationCode":"size = struct.class.members.length\nraise IndexError, \"index #{i} outside 0...#{size}\" unless i.is_a?(Integer) && i >= -size && i < size\nstruct[i] = value","typeGuard":"->(struct, i) { i.is_a?(Integer) && i >= -struct.class.members.length && i < struct.class.members.length }","tryCatchPattern":"begin\n  struct[i] = value\nrescue IndexError => e\n  raise RangeError, \"bad column index #{i}: #{e.message}\"\nend","preventionTips":["Iterate with 0...members.length (exclusive end), never 0..length","Prefer named member access over index arithmetic where possible","Validate externally sourced indices at the trust boundary (row/column numbers from input data)"],"tags":["ruby","struct","index-error","bounds-check","off-by-one"],"backgroundTag":"index-out-of-bounds","analyzedSha":"0b88d5ff75f69b3740c8f0868e76f833cb2fd45d","analyzedAt":"2026-08-21T20:12:56.291Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}