neoclide/coc.nvim · error · Error

pattern \n not supported

Error message

pattern \n not supported

What it means

A newline inside a snippet transform regex is not representable in the JS conversion, which expects a single-line pattern string. convertRegex rejects it early rather than producing a broken regex. Raised while parsing transform patterns in snippet bodies.

Source

Thrown at src/snippets/util.ts:81

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

View on GitHub (pinned to 50e974d969)

Solutions

  1. Remove the newline from the pattern.
  2. Replace the newline matcher with a character-class equivalent like [\s\S] or \s.
  3. Restructure the transform so it matches within a single line.
  4. Validate the snippet string contains no raw newlines inside ${.../regex/.../}.

Example fix

// before
'${1/foo\nbar/x/}'
// after
'${1/foo\\sbar/x/}'
Defensive patterns

Strategy: validation

Validate before calling

function regexIsSingleLine(pattern: string): boolean {
  return !pattern.includes('\n')
}

Type guard

null

Try / catch

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

Prevention

When it happens

Trigger: A snippet transform regex containing a literal \n or an actual newline character inside the pattern.

Common situations: Multi-line patterns pasted from Python snippet definitions; template strings spanning lines in generated snippets.

Related errors


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