teamcapybara/capybara · error · ArgumentError

Invalid CSS Selector - string end not found

Error message

Invalid CSS Selector - string end not found

What it means

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.

Source

Thrown at lib/capybara/selector/css.rb:97

            else
              block += char
            end
          end
          raise ArgumentError, "Invalid CSS Selector - Block end '#{final}' not found"
        end

        def parse_string(quote, strio)
          string = quote
          while (char = strio.getc)
            string += char
            case char
            when quote
              return string
            when '\\'
              string += strio.getc
            end
          end
          raise ArgumentError, 'Invalid CSS Selector - string end not found'
        end
      end
    end
  end
end

View on GitHub (pinned to 15b5fdb76e)

Solutions

  1. Close the quote and keep the inner/outer quote styles distinct: "input[value='foo']".
  2. Escape embedded quotes with a backslash, or switch the outer quoting so the inner quote is legal.
  3. Sanitize data-derived attribute values (escape or strip quotes) before embedding them into selector strings.
  4. Prefer option-hash filters (find(:css, 'input', exact_text: value)) over hand-built selector strings for data-driven values.

Example fix

# before
find(:css, "input[value='foo")

# after
find(:css, "input[value='foo']")
Defensive patterns

Strategy: validation

Validate before calling

def terminated_quotes?(selector)
  %w[' \"].none? do |q| 
    selector.count(q).odd?
  end
end

selector = "input[value='foo"
raise ArgumentError, 'unterminated string in CSS selector' unless terminated_quotes?(selector)

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of teamcapybara/capybara@15b5fdb76e (2026-08-21). Data as JSON: /api/errors/7caeada00ce5311b. Report an issue: GitHub.