{"record":{"id":"b9b08a4beccdb720","repo":"ahmetb/kubectx","slug":"failed-to-save-the-previous-namespace-to-file-w","errorCode":null,"errorMessage":"failed to save the previous namespace to file: %w","messagePattern":"failed to save the previous namespace to file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"cmd/kubens/switch.go","lineNumber":95,"sourceCode":"\tif !force {\n\t\tok, err := namespaceExists(kc, ns)\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"failed to query if namespace exists (is cluster accessible?): %w\", err)\n\t\t}\n\t\tif !ok {\n\t\t\treturn \"\", fmt.Errorf(\"no namespace exists with name \\\"%s\\\"\", ns)\n\t\t}\n\t}\n\n\tif err := kc.SetNamespace(ctx, ns); err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to change to namespace \\\"%s\\\": %w\", ns, err)\n\t}\n\tif err := kc.Save(); err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to save kubeconfig file: %w\", err)\n\t}\n\tif curNS != ns {\n\t\tif err := f.Save(curNS); err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"failed to save the previous namespace to file: %w\", err)\n\t\t}\n\t}\n\treturn ns, nil\n}\n\nfunc namespaceExists(kc *kubeconfig.Kubeconfig, ns string) (bool, error) {\n\t// for tests\n\tif os.Getenv(\"_MOCK_NAMESPACES\") != \"\" {\n\t\treturn ns == \"ns1\" || ns == \"ns2\", nil\n\t}\n\n\tclientset, err := newKubernetesClientSet(kc)\n\tif err != nil {\n\t\treturn false, fmt.Errorf(\"failed to initialize k8s REST client: %w\", err)\n\t}\n\n\tnamespace, err := clientset.CoreV1().Namespaces().Get(context.Background(), ns, metav1.GetOptions{})\n\tif errors2.IsNotFound(err) {","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/ahmetb/kubectx/blob/12ad6fb22e8c546ee2b54e7de38aa51c906832f7/cmd/kubens/switch.go#L77-L113","documentation":"If the namespace actually changed (curNS != ns), switchNamespace records the old namespace in the per-context history file via f.Save(curNS) so `kubens -` can swap back. This error wraps a failure writing that history file — a filesystem-level problem, not a cluster or kubeconfig issue. Note the kubeconfig was already saved, so the switch itself succeeded; only the back/forth bookkeeping failed. Thrown at cmd/kubens/switch.go:95.","triggerScenarios":"f.Save(curNS) errors because the state directory (~/.kube/kubens or XDG equivalent) does not exist and cannot be created, is read-only, has wrong permissions, or the disk is full.","commonSituations":"HOME unset or pointing to a read-only path in CI/cron; kubens state directory deleted by a cleanup job while the process runs; read-only root filesystem in minimal containers; disk quota exceeded.","solutions":["Ensure the state directory is writable: mkdir -p ~/.kube/kubens && chmod u+w ~/.kube/kubens","Check $HOME is set and writable in the environment where kubens runs","Free disk space / raise quota if the filesystem is full","The namespace switch already took effect; only '-' history is lost — re-save by switching namespaces once more after fixing the directory"],"exampleFix":"// before\n# ~/.kube/kubens missing (cleanup job removed it)\nkubens prod   # switch succeeds, history save fails\n// after\nmkdir -p ~/.kube/kubens\nkubens default && kubens prod   # history file recreated","handlingStrategy":"fallback","validationCode":"dir := stateDir()\nif err := os.MkdirAll(dir, 0o755); err != nil {\n    return fmt.Errorf(\"kubens state dir unwritable, '-' history disabled: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := f.Save(curNS); err != nil {\n    // non-fatal: namespace switch already succeeded; log and continue\n    fmt.Fprintf(stderr, \"warning: could not record previous namespace: %v\\n\", err)\n}","preventionTips":["Pre-create ~/.kube/kubens with user-writable permissions in provisioning scripts","Ensure $HOME is set and writable in CI, cron, and containers","Exclude the kubens state directory from aggressive cleanup jobs","Treat this error as non-fatal — the switch itself has already been persisted"],"tags":["filesystem","state","kubens"],"backgroundTag":"state-file-write-failed","analyzedSha":"12ad6fb22e8c546ee2b54e7de38aa51c906832f7","analyzedAt":"2026-09-02T12:23:10.107Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T16:17:10.729Z"}