louis-e/arnis · error · Error

Syntax error, unrecognized expression:

Error message

Syntax error, unrecognized expression: 

What it means

Sizzle (jQuery 1.9.1's CSS selector engine) throws this when passed a selector string it cannot parse or that matches no known expression syntax. jQuery 1.x funnels all selector parsing through Sizzle; an empty, malformed, or unsupported selector reaches Sizzle.error and raises this Error. It is thrown from the parser itself, so it fires synchronously wherever jQuery(cssSelector) or .find()/.filter() is called.

Source

Thrown at src/gui/js/libs/jquery-1.9.1.js:4421

		setDocument( elem );
	}

	if ( !documentIsXML ) {
		name = name.toLowerCase();
	}
	if ( (val = Expr.attrHandle[ name ]) ) {
		return val( elem );
	}
	if ( documentIsXML || support.attributes ) {
		return elem.getAttribute( name );
	}
	return ( (val = elem.getAttributeNode( name )) || elem.getAttribute( name ) ) && elem[ name ] === true ?
		name :
		val && val.specified ? val.value : null;
};

Sizzle.error = function( msg ) {
	throw new Error( "Syntax error, unrecognized expression: " + msg );
};

// Document sorting and removing duplicates
Sizzle.uniqueSort = function( results ) {
	var elem,
		duplicates = [],
		i = 1,
		j = 0;

	// Unless we *know* we can detect duplicates, assume their presence
	hasDuplicate = !support.detectDuplicates;
	results.sort( sortOrder );

	if ( hasDuplicate ) {
		for ( ; (elem = results[i]); i++ ) {
			if ( elem === results[ i - 1 ] ) {
				j = duplicates.push( i );
			}

View on GitHub (pinned to 34048924d9)

Solutions

  1. Inspect the selector string logged in the error message (the part after 'unrecognized expression:') and fix the malformed portion — usually an unbalanced quote or bracket.
  2. Guard for empty/undefined values before building selectors: only call $() when the interpolated variable is a non-empty string.
  3. Replace pseudo-selectors removed or restricted in jQuery 1.9 (see the jQuery 1.9 upgrade guide) or quote string arguments, e.g. :contains("text").
  4. Use .filter(fn) with a predicate function instead of building complex attribute selectors from dynamic data.
  5. If a plugin's custom pseudo-selector is missing, include/update the plugin (e.g. an updated Sizzle-compatible version).

Example fix

// before
$("input[value=" + userInput + "]").hide(); // userInput empty -> Syntax error, unrecognized expression: input[value=]
// after
if (userInput) {
  $("input[value='" + userInput.replace(/'/g, "\\'") + "']").hide();
} else {
  $("input").hide();
}
Defensive patterns

Strategy: validation

Validate before calling

function isSafeSelector(sel) {
  return typeof sel === "string" && sel.trim().length > 0 &&
    !/["'](?![^"']*["'])/.test(sel); // crude unbalanced-quote check
}
if (isSafeSelector(mySelector)) $(mySelector).hide();

Type guard

function isNonEmptyString(v) { return typeof v === "string" && v.trim().length > 0; }

Try / catch

try {
  $(selector).doSomething();
} catch (e) {
  if (/unrecognized expression/.test(e.message)) {
    console.warn("bad selector:", JSON.stringify(selector));
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling jQuery() / $(selector) / .find() / .is() with: an empty string ('' or undefined coerced), unbalanced quotes/parens/brackets (e.g. "div[title='x"), unknown pseudo-selectors (:foo where foo isn't defined and no plugin provides it), or a non-string like a plain object that stringifies to garbage in jQuery 1.9's stricter parser.

Common situations: Selectors built by string concatenation where a variable is empty or undefined ($(frag)); upgrading from jQuery 1.8 to 1.9 which removed removed/changed pseudo-selectors (:contains without quotes, :radio[name=] edge cases, etc.); typos in custom pseudo-selector names; markup-derived attribute values containing quotes used inside selectors.

Related errors


AI-assisted analysis of louis-e/arnis@34048924d9 (2026-09-03). Data as JSON: /api/errors/2d930bbce6324363. Report an issue: GitHub.