{"record":{"id":"99818c25af502fdf","repo":"ahmetb/kubectx","slug":"failed-to-load-previous-namespace-from-file-w","errorCode":null,"errorMessage":"failed to load previous namespace from file: %w","messagePattern":"failed to load previous namespace from file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"cmd/kubens/switch.go","lineNumber":67,"sourceCode":"}\n\nfunc switchNamespace(kc *kubeconfig.Kubeconfig, ns string, force bool) (string, error) {\n\tctx, err := kc.GetCurrentContext()\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to get current context: %w\", err)\n\t}\n\tif ctx == \"\" {\n\t\treturn \"\", errors.New(\"current-context is not set\")\n\t}\n\tcurNS, err := kc.NamespaceOfContext(ctx)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to get current namespace: %w\", err)\n\t}\n\n\tf := NewNSFile(ctx)\n\tprev, err := f.Load()\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to load previous namespace from file: %w\", err)\n\t}\n\n\tif ns == \"-\" {\n\t\tif prev == \"\" {\n\t\t\treturn \"\", fmt.Errorf(\"No previous namespace found for current context (%s)\", ctx)\n\t\t}\n\t\tns = prev\n\t}\n\n\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}","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/ahmetb/kubectx/blob/12ad6fb22e8c546ee2b54e7de38aa51c906832f7/cmd/kubens/switch.go#L49-L85","documentation":"kubens tracks the previous namespace per context in a file created by NewNSFile(ctx); switchNamespace calls f.Load() to read it (needed for the '-' swap). This error wraps a failure to load that state file — a read or parse problem with the namespace history file, not the kubeconfig. Thrown at cmd/kubens/switch.go:67.","triggerScenarios":"f.Load() errors because the namespace file under ~/.kube/kubens/ (or $XDG state dir) is unreadable due to permissions, corrupted/invalid contents, or the home/state directory is inaccessible.","commonSituations":"HOME points to a read-only or nonexistent directory (CI containers, chroot); the state file was partially written by a crashed process; a dotfile-sync tool replaced the directory with a symlink to a missing path.","solutions":["Check the kubens state directory exists and is writable: ls -ld ~/.kube/kubens (or the XDG state path) and mkdir -p/chmod if needed","Delete the corrupted per-context namespace file so kubens recreates it (you lose '-' history only)","Verify $HOME is set and points to a writable directory in your shell/container","If running in CI, expect no history file; switch by explicit namespace name instead of '-'"],"exampleFix":"// before\nkubens -   # fails: state file unreadable\n// after\nrm ~/.kube/kubens/<context-name-file>   # drop corrupted state\nkubens default                          # switch explicitly, history resets","handlingStrategy":"fallback","validationCode":"f := NewNSFile(ctx)\nif _, err := os.Stat(f.Path()); err != nil {\n    // treat as no history instead of failing\n}","typeGuard":null,"tryCatchPattern":"prev, err := f.Load()\nif err != nil {\n    // degrade gracefully: proceed with empty prev, disable '-' support\n    prev = \"\"\n}","preventionTips":["Ensure $HOME is writable wherever kubens runs (CI containers included)","Do not sync ~/.kube/kubens with dotfile tools that replace it via symlink","Avoid killing kubens mid-write; the state file is small and writes are fast"],"tags":["filesystem","state","kubens"],"backgroundTag":"state-file-unreadable","analyzedSha":"12ad6fb22e8c546ee2b54e7de38aa51c906832f7","analyzedAt":"2026-09-02T12:23:10.107Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T16:17:10.729Z"}