neoclide/coc.nvim · error · Error

pattern (?id/name)yes-pattern|no-pattern not supported

Error message

pattern (?id/name)yes-pattern|no-pattern not supported

What it means

Python conditional patterns of the form (?(id)yes|no) are not supported by JavaScript regex, so the snippet transform converter rejects them at parse time. This prevents silently translating a conditional into an invalid or wrong JS pattern.

Source

Thrown at src/snippets/util.ts:84

/**
 * 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
 */
export function getAction(opt: { actions?: { [key: string]: any } } | undefined, action: UltiSnipsAction): string | undefined {
  if (!opt || !opt.actions) return undefined
  return opt.actions[action]
}

View on GitHub (pinned to 50e974d969)

Solutions

  1. Rewrite the conditional using alternation and lookarounds.
  2. Split the transform into multiple simpler transforms if possible.
  3. Remove the conditional if the yes/no branches can be expressed by the replacement string.
  4. Simplify the snippet to avoid the pattern entirely.

Example fix

// before
'${1/(?(1)a|b)/x/}'
// after
'${1/(?:^b|a)/x/}' // express with alternation/lookarounds
Defensive patterns

Strategy: validation

Validate before calling

let conditionRe = /\(\?\(?[\w]+\)?/ // rough conditional-detector
function regexIsPortable(pattern: string): boolean {
  return !/\(\?\(/.test(pattern)
}

Type guard

null

Try / catch

try {
  let js = convertRegex(pattern)
} catch (e) {
  if (String(e.message).includes('yes-pattern')) pattern = rewriteConditional(pattern) // use alternation/lookarounds
}

Prevention

When it happens

Trigger: A snippet transform regex containing a conditional group (?(1)...|...) or (?(name)...|...).

Common situations: Snippets ported from UltiSnips or Python tools that rely on conditional regex constructs.

Related errors


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