{"record":{"id":"2ac77e840584312b","repo":"teamcapybara/capybara","slug":"invalid-css-selector-block-end-final-not-fo","errorCode":null,"errorMessage":"Invalid CSS Selector - Block end '#{final}' not found","messagePattern":"Invalid CSS Selector - Block end '#(.+?)' not found","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/capybara/selector/css.rb","lineNumber":83,"sourceCode":"        def parse_paren(strio)\n          parse_block('(', ')', strio)\n        end\n\n        def parse_block(start, final, strio)\n          block = start\n          while (char = strio.getc)\n            case char\n            when final\n              return block + char\n            when '\\\\'\n              block += char + strio.getc\n            when '\"', \"'\"\n              block += parse_string(char, strio)\n            else\n              block += char\n            end\n          end\n          raise ArgumentError, \"Invalid CSS Selector - Block end '#{final}' not found\"\n        end\n\n        def parse_string(quote, strio)\n          string = quote\n          while (char = strio.getc)\n            string += char\n            case char\n            when quote\n              return string\n            when '\\\\'\n              string += strio.getc\n            end\n          end\n          raise ArgumentError, 'Invalid CSS Selector - string end not found'\n        end\n      end\n    end\n  end","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/teamcapybara/capybara/blob/15b5fdb76e972e9623d5af2123ed3755594f9732/lib/capybara/selector/css.rb#L65-L101","documentation":"Capybara::Selector::CSS is the small parser Capybara uses to split/extend CSS selectors (for example when appending class or attribute conditions to a CSS locator). While scanning a bracket/paren block it consumes characters until the expected closing delimiter; hitting end-of-input first means the selector is unbalanced, and it raises ArgumentError naming the missing 'block end' character (e.g. ']' for an attribute selector or ')' for a functional pseudo-class).","triggerScenarios":"find(:css, 'div[data-id=\\'42\\''); find(:css, 'a:not(.external'); find(:css, 'tr:nth-child(2'); dynamically concatenated selectors where an interpolation dropped the closing bracket; class/attribute option values containing unbalanced brackets that get embedded into the CSS.","commonSituations":"Selector strings built by string interpolation or slicing (truncation cuts the tail); copy-paste from HTML/ERB that loses a character; data-driven selectors from fixtures or CSV; regex captures fed into find(:css, ...).","solutions":["Balance the selector - every '(' and '[' opened must be closed in order.","When building selectors from data, pass values as option hashes (class:, id:, text:) so Capybara escapes them, instead of interpolating raw strings into CSS.","If a selector comes from external data, validate/parse it first (e.g. Nokogiri::CSS.parse) to fail with a clearer message before Capybara's splitting stage.","Check for smart quotes or stray escapes when the selector text was copied out of a browser console or email."],"exampleFix":"# before\nfind(:css, \"div[data-id='42'\")\n\n# after\nfind(:css, \"div[data-id='42']\")","handlingStrategy":"validation","validationCode":"require 'nokogiri'\n\ndef balanced_css?(selector)\n  Nokogiri::CSS.parse(selector)\n  true\nrescue Nokogiri::CSS::SyntaxError\n  false\nend\n\nselector = \"div[data-id='42'\"\nraise ArgumentError, \"unbalanced CSS: #{selector}\" unless balanced_css?(selector)","typeGuard":"def balanced_delimiters?(sel)\n  stack = []\n  sel.each_char do |c|\n    stack.push(c) if %w[( [ {].include?(c)\n    return false if %w[) ] }].include?(c) && stack.pop != { ')' => '(', ']' => '[', '}' => '{' }[c]\n  end\n  stack.empty?\nend","tryCatchPattern":null,"preventionTips":["Build selectors from option hashes (class:, id:, text:) instead of string concatenation so Capybara escapes values.","Validate data-derived selectors with Nokogiri::CSS.parse before passing them to find(:css, ...)."],"tags":["ruby","capybara","css","selector-parsing"],"backgroundTag":"invalid-css-selector","analyzedSha":"15b5fdb76e972e9623d5af2123ed3755594f9732","analyzedAt":"2026-08-21T16:53:45.588Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}