neoclide/coc.nvim · error

${this.def} is not a valid coc extension, "engines" field wi

Error message

${this.def} is not a valid coc extension, "engines" field with coc property required.

What it means

thrown when the registry metadata for the chosen version lacks an 'engines' object with a 'coc' property. coc.nvim requires extensions to declare which coc.nvim engine versions they support; without it the package is not treated as a valid coc extension.

Source

Thrown at src/extension/installer.ts:236

          let versions = Object.keys(res.versions ?? {}).filter(version => {
            let published = Date.parse(res.time?.[version])
            return Number.isFinite(published) && published <= cutoff
          })
          this.version = semver.maxSatisfying(versions, '*') ?? undefined
          if (!this.version) throw new Error(`${this.def} has no release older than ${releaseAge} days.`)
        }
      }
    } else if (releaseAge > 0) {
      let published = Date.parse(res.time?.[this.version])
      let cutoff = Date.now() - releaseAge * 24 * 60 * 60 * 1000
      if (!Number.isFinite(published) || published > cutoff) {
        throw new Error(`${this.def} is not older than ${releaseAge} days.`)
      }
    }
    let obj = res['versions'][this.version]
    if (!obj) throw new Error(`${this.def} doesn't exists in ${registry}.`)
    let requiredVersion = obj['engines'] && obj['engines']['coc']
    if (!requiredVersion) throw new Error(`${this.def} is not a valid coc extension, "engines" field with coc property required.`)
    extensionPath(this.root, res.name)
    return {
      'dist.tarball': obj['dist']['tarball'],
      'engines.coc': requiredVersion,
      version: obj['version'],
      name: res.name
    } as Info
  }

  public async getInfoFromUri(): Promise<Info> {
    let { url } = this
    let repository: URL
    try {
      repository = new URL(url)
    } catch (_e) {
      throw new Error(`"${url}" is not supported, coc.nvim support github.com only`)
    }
    if (repository.protocol !== 'https:' || repository.hostname !== 'github.com') {

View on GitHub (pinned to 50e974d969)

Solutions

  1. Verify the package is a real coc extension (its package.json contains "engines": {"coc": ...}).
  2. Check the extension name spelling in the def/url.
  3. If it is your own extension, add engines: { "coc": ">=x.y.z" } to package.json and publish.
  4. If using a custom branch/tarball, make sure it builds a proper package.json with engines.coc.

Example fix

// package.json of the extension
// before
{ "name": "my-ext", "version": "1.0.0" }
// after
{ "name": "my-ext", "version": "1.0.0", "engines": { "coc": ">=0.0.80" } }
Defensive patterns

Strategy: validation

Validate before calling

const meta = await npmView(name)
if (!(meta.engines && meta.engines.coc)) throw new Error(`${name} is not a coc extension`)
await installer.install()

Type guard

function isCocExt(pkg) { return !!pkg && typeof pkg.engines === 'object' && pkg.engines !== null && typeof pkg.engines.coc === 'string' }

Try / catch

try { await installer.install() } catch (e) { if (e.message.includes('is not a valid coc extension')) { /* notify: wrong package name / not a coc ext */ } else { throw e } }

Prevention

When it happens

Trigger: getInfo resolves a registry version whose package.json has no engines.coc field — e.g. installing an arbitrary npm package by name that is not a coc extension.

Common situations: Misspelling an extension name so a non-coc npm package is installed; a broken/misconfigured extension package; very old or hand-built packages predating the engines.coc convention.

Related errors


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