{"record":{"id":"534f5de6cdda337b","repo":"google-gemini/gemini-cli","slug":"extension-previousname-was-not-already-instal","errorCode":null,"errorMessage":"Extension \"${previousName}\" was not already installed, cannot update it.","messagePattern":"Extension \"(.+?)\" was not already installed, cannot update it\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/config/extension-manager.ts","lineNumber":310,"sourceCode":"        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(\n            `Extension \"${previousName}\" was not already installed, cannot update it.`,\n          );\n        } else if (!isUpdate && previous) {\n          throw new Error(\n            `Extension \"${newExtensionName}\" is already installed. Please uninstall it first.`,\n          );\n        } else if (isUpdate && nameConflict) {\n          throw new Error(\n            `Cannot update to \"${newExtensionName}\" because an extension with that name is already installed.`,\n          );\n        }\n\n        const newHasHooks = fs.existsSync(\n          path.join(localSourcePath, 'hooks', 'hooks.json'),\n        );\n        const previousHasHooks = !!(\n          isUpdate &&\n          previous &&","sourceCodeStart":292,"sourceCodeEnd":328,"githubUrl":"https://github.com/google-gemini/gemini-cli/blob/5024443c7217464a66e98f80d73172a26440bd8f/packages/cli/src/config/extension-manager.ts#L292-L328","documentation":"Thrown on the update path (`previousExtensionConfig` was supplied, so `isUpdate` is true) when no currently-loaded extension matches `previousName`. The update logic needs the previous extension's hooks/skills/enablement state to migrate cleanly, so a missing previous extension is fatal.","triggerScenarios":"The previous extension's directory was manually deleted from disk while its config entry persisted; `loadExtensions` skipped it due to a load error; the extension was renamed on disk but the config still references the old name.","commonSituations":"Manual `rm -rf` of an extension directory; a failed uninstall that left config behind; switching machines with a partial sync; corrupted extension state.","solutions":["Uninstall the dangling config entry first, then install fresh instead of updating.","Reinstall the previous version so the extension is loadable, then retry the update.","Inspect `~/.gemini/extensions/` and remove stale entries before retrying."],"exampleFix":"// before\ninstallOrUpdateExtension(meta, previousConfig)  // previous no longer on disk\n// after\nawait uninstallExtension(previousName); await installOrUpdateExtension(meta)","handlingStrategy":"validation","validationCode":"const previous = extensionManager.getExtensions().find((e) => e.name === previousName);\nif (isUpdate && !previous) {\n  throw new Error(`Cannot update ${previousName}: not installed.`);\n}","typeGuard":"function isInstalled(name: string, installed: { name: string }[]): boolean {\n  return installed.some((e) => e.name === name);\n}","tryCatchPattern":null,"preventionTips":["Before calling update, confirm the previous extension loads via `getExtensions()`.","If a directory was deleted manually, run uninstall first to clean the config.","Don't rely on stale `previousExtensionConfig` after a manual cleanup."],"tags":["extensions","update","state-mismatch"],"backgroundTag":null,"analyzedSha":"5024443c7217464a66e98f80d73172a26440bd8f","analyzedAt":"2026-08-12T06:01:53.711Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}