{"record":{"id":"cbfab0d0a9542616","repo":"derailed/k9s","slug":"context-with-name-s-already-exists","errorCode":null,"errorMessage":"context with name %s already exists","messagePattern":"context with name (.+?) already exists","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/client/config.go","lineNumber":242,"sourceCode":"\tdelete(cfg.Contexts, n)\n\n\tacc, err := c.ConfigAccess()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn clientcmd.ModifyConfig(acc, cfg, true)\n}\n\n// RenameContext renames a context.\nfunc (c *Config) RenameContext(oldCtx, newCtx string) error {\n\tcfg, err := c.RawConfig()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif _, ok := cfg.Contexts[newCtx]; ok {\n\t\treturn fmt.Errorf(\"context with name %s already exists\", newCtx)\n\t}\n\tcfg.Contexts[newCtx] = cfg.Contexts[oldCtx]\n\tdelete(cfg.Contexts, oldCtx)\n\tacc, err := c.ConfigAccess()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif e := clientcmd.ModifyConfig(acc, cfg, true); e != nil {\n\t\treturn e\n\t}\n\tcurrent, err := c.CurrentContextName()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif current == oldCtx {\n\t\treturn c.SwitchContext(newCtx)\n\t}\n","sourceCodeStart":224,"sourceCodeEnd":260,"githubUrl":"https://github.com/derailed/k9s/blob/2d3ccc6ba2ce98c3781bfc441bb3e884f072774f/internal/client/config.go#L224-L260","documentation":"Returned by Config.RenameContext (internal/client/config.go:242) when the destination name newCtx already exists in the kubeconfig contexts map. Rename is implemented as copy-then-delete and refuses to overwrite, so an existing target aborts the operation before any mutation. The check happens after RawConfig, so kubeconfig readability is implied.","triggerScenarios":"Calling RenameContext(\"old\", \"dev\") when a context literally named 'dev' already exists; case-variant names on case-insensitive lookups; re-running a rename script that failed halfway on the second attempt.","commonSituations":"kubectx-style rename flows; consolidating duplicate contexts and picking a colliding name; scripted kubeconfig hygiene where the target was pre-created by another team member.","solutions":["Choose a different, unused target name (verify with kubectl config get-contexts)","If the existing target is disposable, delete it first: kubectl config delete-context <newCtx>, then rename","If both must survive, merge their settings manually instead of renaming over"],"exampleFix":"# before\ncfg.RenameContext(\"old-cluster\", \"dev\")  # 'dev' exists -> error\n\n# after\nkubectl config delete-context dev\ncfg.RenameContext(\"old-cluster\", \"dev\")","handlingStrategy":"validation","validationCode":"func renameSafe(cfg *client.Config, oldName, newName string) error {\n\tctxs, err := cfg.Contexts()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif _, exists := ctxs[newName]; exists {\n\t\treturn fmt.Errorf(\"target name %q taken; pick another or delete it first\", newName)\n\t}\n\tif _, ok := ctxs[oldName]; !ok {\n\t\treturn fmt.Errorf(\"source context %q not found\", oldName)\n\t}\n\treturn cfg.RenameContext(oldName, newName)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Derive new names from the existing context list to guarantee uniqueness","Make rename scripts idempotent: check existence of both old and new before acting","Prefer kubectx <old>=<new> semantics awareness: same guard exists there"],"tags":["kubernetes","kubeconfig","context","rename","validation"],"backgroundTag":null,"analyzedSha":"2d3ccc6ba2ce98c3781bfc441bb3e884f072774f","analyzedAt":"2026-08-15T16:09:14.432Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}