{"record":{"id":"7caeada00ce5311b","repo":"teamcapybara/capybara","slug":"invalid-css-selector-string-end-not-found","errorCode":null,"errorMessage":"Invalid CSS Selector - string end not found","messagePattern":"Invalid CSS Selector - string end not found","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/capybara/selector/css.rb","lineNumber":97,"sourceCode":"            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\nend\n","sourceCodeStart":79,"sourceCodeEnd":103,"githubUrl":"https://github.com/teamcapybara/capybara/blob/15b5fdb76e972e9623d5af2123ed3755594f9732/lib/capybara/selector/css.rb#L79-L103","documentation":"Companion to the block-end error: while scanning a quoted string inside a CSS selector, Capybara::Selector::CSS#parse_string reached end-of-input before the closing quote. The selector is syntactically unterminated (single or double quote opened and never closed), and the parser refuses it with ArgumentError instead of passing a broken string downstream.","triggerScenarios":"find(:css, \"input[value='foo\"); find(:css, 'a[href=\\\"http://x'); interpolation that leaves an unclosed quote: \"td[title='#{value}\" where value's trailing quote was forgotten.","commonSituations":"String interpolation with mixed quote styles (using \" inside a \"-quoted selector); truncation of long selectors; pasting selectors through shells/ERB that eat a quote; building attribute values from user data containing quote characters.","solutions":["Close the quote and keep the inner/outer quote styles distinct: \"input[value='foo']\".","Escape embedded quotes with a backslash, or switch the outer quoting so the inner quote is legal.","Sanitize data-derived attribute values (escape or strip quotes) before embedding them into selector strings.","Prefer option-hash filters (find(:css, 'input', exact_text: value)) over hand-built selector strings for data-driven values."],"exampleFix":"# before\nfind(:css, \"input[value='foo\")\n\n# after\nfind(:css, \"input[value='foo']\")","handlingStrategy":"validation","validationCode":"def terminated_quotes?(selector)\n  %w[' \\\"].none? do |q| \n    selector.count(q).odd?\n  end\nend\n\nselector = \"input[value='foo\"\nraise ArgumentError, 'unterminated string in CSS selector' unless terminated_quotes?(selector)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use distinct inner/outer quote styles when interpolating: \\\"input[value='#{v}']\\\".","Escape or strip quote characters in data before embedding them into selectors."],"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"}