dotnet/AspNetCore.Docs · error · Error

Syntax error, unrecognized expression: ${msg}

Error message

Syntax error, unrecognized expression: ${msg}

What it means

jQuery 2.x uses Sizzle as its selector engine. Sizzle.error is the single choke point for any unparseable selector passed to $(), .find(), .filter(), .children(), etc. The thrown message appends the offending expression so you can see what failed. HTML strings that look like selectors and selectors with unescaped metacharacters both end here.

Source

Thrown at aspnetcore/mvc/controllers/testing/samples/2.x/TestingControllersSample/src/TestingControllersSample/wwwroot/js/jquery-2.2.0.js:1463

        }
    
        var fn = Expr.attrHandle[ name.toLowerCase() ],
            // Don't get fooled by Object.prototype properties (jQuery #13807)
            val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
                fn( elem, name, !documentIsHTML ) :
                undefined;
    
        return val !== undefined ?
            val :
            support.attributes || !documentIsHTML ?
                elem.getAttribute( name ) :
                (val = elem.getAttributeNode(name)) && val.specified ?
                    val.value :
                    null;
    };
    
    Sizzle.error = function( msg ) {
        throw new Error( "Syntax error, unrecognized expression: " + msg );
    };
    
    /**
     * Document sorting and removing duplicates
     * @param {ArrayLike} results
     */
    Sizzle.uniqueSort = function( results ) {
        var elem,
            duplicates = [],
            j = 0,
            i = 0;
    
        // Unless we *know* we can detect duplicates, assume their presence
        hasDuplicate = !support.detectDuplicates;
        sortInput = !support.sortStable && results.slice( 0 );
        results.sort( sortOrder );
    
        if ( hasDuplicate ) {

View on GitHub (pinned to c67a80103a)

Solutions

  1. Escape metacharacters with $.escapeSelector (jQuery 3+) or a manual escape: id.replace(/([.:#\[\],])/g, '\\$1').
  2. Prefer document.getElementById and wrap with $(): $(document.getElementById('a.b.c')).
  3. If you meant HTML, make it a valid complete tag string.
  4. Sanitize/validate any user-supplied string before using it as a selector.

Example fix

// before
$('.price[special]'); // or $('#user.name'); // throws on weird ids
// after
$('#' + $.escapeSelector('user.name'));
// or
$(document.getElementById('user.name'));
Defensive patterns

Strategy: validation

Validate before calling

// Escape metacharacters before building selectors from dynamic ids.
function safeIdSelector(id) {
  return '#' + (window.jQuery && jQuery.escapeSelector ? jQuery.escapeSelector(id) : id.replace(/([!\"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g, '\\$1'));
}
$(safeIdSelector(dynamicId)).hide();

Type guard

function looksLikeValidSelector(s) {
  if (typeof s !== 'string' || s.length === 0) return false;
  try { $(s); return true; } catch (e) { return false; }
}

Try / catch

try {
  return $(userSelector);
} catch (e) {
  if (/Syntax error, unrecognized expression/.test(e.message)) {
    console.warn('Invalid selector, ignoring:', userSelector);
    return $(); // empty collection
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling $('#a.b') (dot treated as class), $('.foo:bar'), $('<div') malformed HTML parsed as selector, $(null) in some paths, or interpolating user input directly into a selector.

Common situations: Element IDs containing dots/colons/brackets; dynamically built selectors from data attributes; copy-pasting a CSS selector that uses pseudo-classes Sizzle doesn't support.

Related errors


AI-assisted analysis of dotnet/AspNetCore.Docs@c67a80103a (2026-08-13). Data as JSON: /api/errors/1fc835b29508c5ef. Report an issue: GitHub.