neoclide/coc.nvim · error

pattern (?x) not supported

Error message

pattern (?x) not supported

What it means

Python's (?x) verbose/extended-mode inline flag is unsupported in the JS regex conversion for snippet transforms. The converter throws at parse time to avoid compiling a pattern whose whitespace/comment semantics would differ in JavaScript.

Source

Thrown at src/snippets/util.ts:78

const conditionRe = /\(\?\(\w+\).+\|/
const commentRe = /\(\?#.*?\)/
const namedCaptureRe = /\(\?P<\w+>.*?\)/
const namedReferenceRe = /\(\?P=(\w+)\)/
const regex = new RegExp(`${commentRe.source}|${stringStartRe.source}|${namedCaptureRe.source}|${namedReferenceRe.source}`, 'g')

/**
 * Convert python regex to javascript regex,
 * throw error when unsupported pattern found
 */
export function convertRegex(str: string): string {
  if (str.indexOf('\\z') !== -1) {
    throw new Error('pattern \\z not supported')
  }
  if (str.indexOf('(?s)') !== -1) {
    throw new Error('pattern (?s) not supported')
  }
  if (str.indexOf('(?x)') !== -1) {
    throw new Error('pattern (?x) not supported')
  }
  if (str.indexOf('\n') !== -1) {
    throw new Error('pattern \\n not supported')
  }
  if (conditionRe.test(str)) {
    throw new Error('pattern (?id/name)yes-pattern|no-pattern not supported')
  }
  return str.replace(regex, (match, p1) => {
    if (match.startsWith('(?#')) return ''
    if (match.startsWith('(?P<')) return '(?' + match.slice(3)
    if (match.startsWith('(?P=')) return `\\k<${p1}>`
    // if (match == '\\A') return '^'
    return '^'
  })
}

/**
 * Action code from context or option

View on GitHub (pinned to 50e974d969)

Solutions

  1. Remove (?x) and collapse the pattern to a single line.
  2. Strip insignificant whitespace and comments from the pattern manually.
  3. Simplify the transform regex.
  4. Test the snippet after edit via snippetManager to confirm parsing succeeds.

Example fix

// before
'${1/(?x) foo \\d+ /x/}'
// after
'${1/ foo \\d+ /x/}'
Defensive patterns

Strategy: validation

Validate before calling

function regexIsPortable(pattern: string): boolean {
  return !pattern.includes('(?x)')
}

Type guard

null

Try / catch

try {
  let js = convertRegex(pattern)
} catch (e) {
  if (String(e.message).includes('(?x)')) pattern = collapseVerboseRegex(pattern) // strip whitespace/comments
}

Prevention

When it happens

Trigger: A snippet transform regex containing (?x) or free-spacing formatting (whitespace/comments in the pattern).

Common situations: Snippets copied from Python-based snippet engines (UltiSnips) that use verbose regexes.

Related errors


AI-assisted analysis of neoclide/coc.nvim@50e974d969 (2026-08-31). Data as JSON: /api/errors/8ae52b4621af21d1. Report an issue: GitHub.