{"record":{"id":"b9b0925f9d4a1003","repo":"google-gemini/gemini-cli","slug":"unsupported-install-type-installmetadata-type","errorCode":null,"errorMessage":"Unsupported install type: ${installMetadata.type}","messagePattern":"Unsupported install type: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/config/extension-manager.ts","lineNumber":292,"sourceCode":"Would you like to attempt to install via \"git clone\" instead?`,\n            ))\n          ) {\n            await cloneFromGit(installMetadata, tempDir);\n            installMetadata.type = 'git';\n          } else {\n            throw new Error(\n              `Failed to install extension ${installMetadata.source}: ${result.errorMessage}`,\n            );\n          }\n        }\n        localSourcePath = tempDir;\n      } else if (\n        installMetadata.type === 'local' ||\n        installMetadata.type === 'link'\n      ) {\n        localSourcePath = getRealPath(installMetadata.source);\n      } else {\n        throw new Error(`Unsupported install type: ${installMetadata.type}`);\n      }\n\n      try {\n        newExtensionConfig = await this.loadExtensionConfig(localSourcePath);\n\n        const newExtensionName = newExtensionConfig.name;\n        const previousName = previousExtensionConfig?.name ?? newExtensionName;\n        const previous = this.getExtensions().find(\n          (installed) => installed.name === previousName,\n        );\n        const nameConflict = this.getExtensions().find(\n          (installed) =>\n            installed.name === newExtensionName &&\n            installed.name !== previousName,\n        );\n\n        if (isUpdate && !previous) {\n          throw new Error(","sourceCodeStart":274,"sourceCodeEnd":310,"githubUrl":"https://github.com/google-gemini/gemini-cli/blob/5024443c7217464a66e98f80d73172a26440bd8f/packages/cli/src/config/extension-manager.ts#L274-L310","documentation":"Defensive `default` branch when `installMetadata.type` is not one of `git`, `github-release`, `local`, or `link`. By the time control reaches this branch, the source has not been resolved to a local path. Normal CLI paths only ever produce the four supported types, so this typically indicates a malformed extension-config file or a programmatic caller passing an invalid type.","triggerScenarios":"Calling `installOrUpdateExtension` directly with a synthetic `ExtensionInstallMetadata` whose `type` is something like `'npm'` or `'tarball'`; a corrupt `install_metadata.json` written by a future or third-party tool.","commonSituations":"Programmatic use of the ExtensionManager; an extension config produced by an incompatible version; manual edits to on-disk metadata.","solutions":["Set `installMetadata.type` to one of `git`, `github-release`, `local`, `link` before calling install.","If migrating from a different install mechanism, re-install through the supported CLI command.","Delete the on-disk `install_metadata.json` and reinstall from a known source."],"exampleFix":"// before\ninstallOrUpdateExtension({ source: url, type: 'tarball' })\n// after\ninstallOrUpdateExtension({ source: localDir, type: 'local' })","handlingStrategy":"type-guard","validationCode":"const SUPPORTED = new Set(['git', 'github-release', 'local', 'link']);\nif (!SUPPORTED.has(installMetadata.type)) {\n  throw new Error(`Unsupported install type: ${installMetadata.type}`);\n}","typeGuard":"const INSTALL_TYPES = ['git', 'github-release', 'local', 'link'] as const;\ntype InstallType = (typeof INSTALL_TYPES)[number];\nfunction isInstallType(v: unknown): v is InstallType {\n  return typeof v === 'string' && (INSTALL_TYPES as readonly string[]).includes(v);\n}","tryCatchPattern":null,"preventionTips":["Constrain `ExtensionInstallMetadata.type` to the supported literal union in your types.","Validate programmatic inputs before calling the manager.","Avoid hand-editing `install_metadata.json`."],"tags":["extensions","install","defensive","type"],"backgroundTag":null,"analyzedSha":"5024443c7217464a66e98f80d73172a26440bd8f","analyzedAt":"2026-08-12T06:01:53.711Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}