{"record":{"id":"7b6f5fe68afeaa35","repo":"neoclide/coc.nvim","slug":"unable-to-load-extension-at-extensionroot-miss","errorCode":null,"errorMessage":"Unable to load extension at ${extensionRoot}, missing package.json","messagePattern":"Unable to load extension at (.+?), missing package\\.json","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/extension/manager.ts","lineNumber":655,"sourceCode":"      void window.showInformationMessage(`watching ${item.directory}`)\n      client.subscribe('**/*.js', async () => {\n        this.reloadExtension(id).then(() => {\n          void window.showInformationMessage(`reloaded ${id}`)\n        }, onUnexpectedError)\n      })\n    }\n  }\n\n  /**\n   * load extension in folder or file\n   */\n  public async load(filepath: string, active: boolean, options?: ExtensionLoadOptions): Promise<ExportExtension> {\n    let name: string\n    if (options?.sourceCode) {\n      let extensionRoot = options.extensionRoot ?? filepath\n      let obj = loadJson(path.join(extensionRoot, 'package.json')) as any\n      name = obj.name\n      if (!name) throw new Error(`Unable to load extension at ${extensionRoot}, missing package.json`)\n      await this.unloadExtension(name)\n      await this.registerExtension(extensionRoot, obj, ExtensionType.Local, true, options)\n    } else if (isDirectory(filepath)) {\n      let obj = loadJson(path.join(filepath, 'package.json')) as any\n      name = obj.name\n      await this.loadExtension(filepath, true)\n    } else {\n      name = await this.loadExtensionFile(filepath, true)\n    }\n    if (!name) throw new Error(`Unable to load extension at ${filepath}`)\n    let disabled = this.states.isDisabled(name)\n    if (disabled) throw new Error(`extension ${name} is disabled`)\n    let item = this.getExtension(name)\n    if (active) await this.activate(name)\n    return {\n      get isActive() {\n        return item.extension.isActive\n      },","sourceCodeStart":637,"sourceCodeEnd":673,"githubUrl":"https://github.com/neoclide/coc.nvim/blob/50e974d9692461a69147d5cab146a8d3e439abe4/src/extension/manager.ts#L637-L673","documentation":"Thrown by ExtensionManager.load() when loading a source-code extension whose root folder has no readable package.json, or the parsed JSON has no `name` field. coc.nvim requires a package.json manifest to identify and register an extension. It indicates the given extensionRoot does not contain a valid extension.","triggerScenarios":"Calling coc.extensions.load(filepath, active, {sourceCode: true}) where options.extensionRoot (default filepath) is a directory without package.json, or the package.json lacks a `name` field, or JSON.parse fails silently returning an object without name.","commonSituations":"Pointing load() at the source file instead of the project root; loading an extension folder that was never built/cloned fully; a malformed package.json; typo'd extensionRoot path.","solutions":["Ensure extensionRoot points to the directory containing a valid package.json with a `name` field","Verify package.json parses as valid JSON (`cat package.json | node -e 'JSON.parse(require(\"fs\").readFileSync(0))'`)","Add or fix the `name` field in package.json","Check the path exists and is the extension root, not a subfolder"],"exampleFix":"// before\nawait coc.extensions.load('/path/to/ext/index.js', true, { sourceCode: true })\n// after\nawait coc.extensions.load('/path/to/ext', true, { sourceCode: true }) // dir containing package.json","handlingStrategy":"validation","validationCode":"const fs = require('fs');\nconst root = options?.extensionRoot ?? filepath;\nconst pkgPath = require('path').join(root, 'package.json');\nif (!fs.existsSync(pkgPath)) throw new Error(`No package.json at ${root}`);\nconst pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));\nif (!pkg.name) throw new Error(`package.json at ${root} has no name`);","typeGuard":null,"tryCatchPattern":"try {\n  await coc.extensions.load(filepath, true, { sourceCode: true });\n} catch (e) {\n  if (String(e.message).includes('missing package.json')) {\n    // fall back or prompt user to fix extension root\n  } else throw e;\n}","preventionTips":["Always pass the extension root directory (containing package.json), not an entry file","Validate package.json name field before load","Run JSON.parse validation in CI for local extensions"],"tags":["extension","configuration","package-json"],"backgroundTag":"missing-package-json","analyzedSha":"50e974d9692461a69147d5cab146a8d3e439abe4","analyzedAt":"2026-08-31T11:17:23.966Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}