{"record":{"id":"186162546560f6c0","repo":"teamcapybara/capybara","slug":"cols-must-be-an-array-of-arrays","errorCode":null,"errorMessage":":cols must be an Array of Arrays","messagePattern":":cols must be an Array of Arrays","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/capybara/selector/definition/table.rb","lineNumber":46,"sourceCode":"      else\n        cells_xp = col.reduce(nil) do |prev_cell, cell_str|\n          cell_condition = XPath.string.n.is(cell_str)\n\n          if prev_cell\n            prev_cell = XPath.ancestor(:tr)[1].preceding_sibling(:tr).join(prev_cell)\n            cell_condition &= (prev_cell & prev_col_position?(prev_cell))\n          end\n\n          XPath.descendant(:td)[cell_condition]\n        end\n        XPath.descendant(:tr).join(cells_xp)\n      end\n    end.reduce(:&)\n    xpath[col_conditions]\n  end\n\n  expression_filter(:cols, valid_values: [Array]) do |xpath, cols|\n    raise ArgumentError, ':cols must be an Array of Arrays' unless cols.all?(Array)\n\n    rows = cols.transpose\n    col_conditions = rows.map { |row| match_row(row, match_size: true) }.reduce(:&)\n    xpath[match_row_count(rows.size)][col_conditions]\n  end\n\n  expression_filter(:with_rows, valid_values: [Array]) do |xpath, rows|\n    rows_conditions = rows.map { |row| match_row(row) }.reduce(:&)\n    xpath[rows_conditions]\n  end\n\n  expression_filter(:rows, valid_values: [Array]) do |xpath, rows|\n    rows_conditions = rows.map { |row| match_row(row, match_size: true) }.reduce(:&)\n    xpath[match_row_count(rows.size)][rows_conditions]\n  end\n\n  describe_expression_filters do |caption: nil, **|\n    \" with caption \\\"#{caption}\\\"\" if caption","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/teamcapybara/capybara/blob/15b5fdb76e972e9623d5af2123ed3755594f9732/lib/capybara/selector/definition/table.rb#L28-L64","documentation":"The :table selector's :cols expression filter describes table contents column-by-column: it expects an Array whose elements are themselves Arrays (one inner array per column; the filter transposes them into rows to build XPath conditions). If any element is not an Array - strings, a flat list, or a nested scalar - the filter raises ArgumentError demanding 'an Array of Arrays'.","triggerScenarios":"find(:table, 'Users', cols: %w[Name Age]); find(:table, 'Matrix', cols: 'Name'); find(:table, 'Users', cols: [['Name', 'Age'], 'foo']) - the first two (and the third's last element) fail cols.all?(Array).","commonSituations":"Passing row-oriented data to :cols by confusing it with the sibling :rows / :with_rows filters (which accept flat inner values row-wise); forgetting the outer wrapping for a single column; generating the structure from JSON/YAML fixtures whose nesting differs.","solutions":["Wrap each column in its own array: cols: [%w[Name John], %w[Age 30]] (each inner array is one column's cell contents, top to bottom).","If your data is row-oriented, use the row-wise filters instead: find(:table, 'Users', rows: [%w[Name Age], %w[John 30]]) or with_rows:.","For a single column, still nest it: cols: [%w[Total]] or cols: [['Total', 'Sum']].","Validate fixture-derived structures with cols.all?(Array) (or an arity/type check) before the query so failures point at the data."],"exampleFix":"# before\nfind(:table, 'Users', cols: %w[Name Age])\n\n# after\nfind(:table, 'Users', cols: [%w[Name John], %w[Age 30]])","handlingStrategy":"validation","validationCode":"cols = [%w[Name John], %w[Age 30]]\nraise ArgumentError, ':cols must be an Array of Arrays' unless cols.is_a?(Array) && cols.all?(Array)\nfind(:table, 'Users', cols: cols)","typeGuard":"def cols_shape?(value)\n  value.is_a?(Array) && value.all?(Array)\nend","tryCatchPattern":null,"preventionTips":["Remember :cols is column-major (each inner array is one column) while :rows/:with_rows are row-major; pick the filter matching your data's orientation.","Validate fixture-derived table data with cols.all?(Array) before querying so failures point at the data source."],"tags":["ruby","capybara","table-selector","filters","data-shape"],"backgroundTag":"invalid-argument-type","analyzedSha":"15b5fdb76e972e9623d5af2123ed3755594f9732","analyzedAt":"2026-08-21T16:53:45.588Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}