neoclide/coc.nvim · error

pattern (?s) not supported

Error message

pattern (?s) not supported

What it means

Python's (?s) inline flag (dot matches newline) is not supported by the JS regex converter used for snippet transforms. convertRegex throws early so snippets fail loudly at parse time instead of silently misbehaving. Raised while parsing ${var/regex/repl/} transforms.

Source

Thrown at src/snippets/util.ts:75

}

const stringStartRe = /\\A/
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 '^'
  })
}

View on GitHub (pinned to 50e974d969)

Solutions

  1. Remove (?s) from the regex.
  2. In JS, use the s (dotAll) flag semantics by matching [\s\S] instead of '.', since transform regexes are compiled without flags.
  3. Split the transform to avoid needing dotall matching.
  4. Rewrite the replacement logic in the snippet differently.

Example fix

// before
'${1/(?s).*/x/}'
// after
'${1/[\\s\\S]*/x/}'
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

null

Try / catch

try {
  let js = convertRegex(pattern)
} catch (e) {
  if (String(e.message).includes('(?s)')) pattern = pattern.replace('(?s)', '').replace(/\./g, '[\\s\\S]')
}

Prevention

When it happens

Trigger: A snippet transform regex containing the inline flag (?s), e.g. ${1/(?s).*/x/}.

Common situations: Porting VS Code/UltiSnips snippets that rely on (?s) multiline matching.

Related errors


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