{"record":{"id":"eaabee50d72bc353","repo":"derailed/k9s","slug":"expecting-context-path-eaabee","errorCode":null,"errorMessage":"expecting context Path","messagePattern":"expecting context Path","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/dao/reference.go","lineNumber":51,"sourceCode":"\t\treturn r.Scan(ctx)\n\t}\n}\n\n// Get fetch a given reference.\nfunc (*Reference) Get(context.Context, string) (runtime.Object, error) {\n\tpanic(\"NYI\")\n}\n\n// Scan scan cluster resources for references.\nfunc (r *Reference) Scan(ctx context.Context) ([]runtime.Object, error) {\n\trefs, err := ScanForRefs(ctx, r.Factory)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfqn, ok := ctx.Value(internal.KeyPath).(string)\n\tif !ok {\n\t\treturn nil, errors.New(\"expecting context Path\")\n\t}\n\tns, _ := client.Namespaced(fqn)\n\too := make([]runtime.Object, 0, len(refs))\n\tfor _, ref := range refs {\n\t\t_, n := client.Namespaced(ref.FQN)\n\t\too = append(oo, render.ReferenceRes{\n\t\t\tNamespace: ns,\n\t\t\tName:      n,\n\t\t\tGVR:       ref.GVR,\n\t\t})\n\t}\n\n\treturn oo, nil\n}\n\n// ScanSA scans for serviceaccount refs.\nfunc (r *Reference) ScanSA(ctx context.Context) ([]runtime.Object, error) {\n\trefs, err := ScanForSARefs(ctx, r.Factory)","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/derailed/k9s/blob/2d3ccc6ba2ce98c3781bfc441bb3e884f072774f/internal/dao/reference.go#L33-L69","documentation":"Reference.Scan has already run ScanForRefs successfully, then reads the resource FQN from ctx.Value(internal.KeyPath) to namespace the rendered ReferenceRes rows. If no string was stored under internal.KeyPath the scan results are discarded and this error returned. The key carries the selected resource path (namespace/name) set by the invoking view.","triggerScenarios":"Invoking Reference.List/Scan with a context missing context.WithValue(ctx, internal.KeyPath, fqn); KeyPath present but holding a non-string value so the type assertion fails.","commonSituations":"Custom views or tests calling the references DAO directly; a navigation path that builds a fresh context for the reference view but forgets to propagate the selected item's path (compare view/helpers.go:136 and view/browser.go:638 which set it).","solutions":["Set the path before scanning: ctx = context.WithValue(ctx, internal.KeyPath, fqn) where fqn is the selected resource's namespace/name.","Reuse the context-building helpers in internal/view (e.g. browser.go:637-638 sets KeyGVR and KeyPath together) so both keys are always present.","In tests, seed the context the way dao/container_test.go:34 does: context.WithValue(context.Background(), internal.KeyPath, \"ns/name\")."],"exampleFix":"// before\nctx := context.Background()\noo, err := ref.List(ctx, \"\") // -> expecting context Path\n// after\nctx = context.WithValue(ctx, internal.KeyGVR, client.SecGVR)\nctx = context.WithValue(ctx, internal.KeyPath, \"default/my-secret\")\noo, err := ref.List(ctx, \"\")","handlingStrategy":"validation","validationCode":"func withPath(ctx context.Context, fqn string) context.Context {\n    return context.WithValue(ctx, internal.KeyPath, fqn)\n}\n\nif _, ok := ctx.Value(internal.KeyPath).(string); !ok {\n    ctx = withPath(ctx, \"default/my-secret\")\n}","typeGuard":"func pathFromCtx(ctx context.Context) (string, bool) {\n    p, ok := ctx.Value(internal.KeyPath).(string)\n    return p, ok\n}","tryCatchPattern":null,"preventionTips":["Always set KeyPath whenever you set KeyGVR when driving the references DAO.","Reuse view-layer helpers (internal/view/helpers.go:136) rather than hand-building contexts.","Add a unit test asserting List succeeds with the keys present."],"tags":["go","kubernetes","context","dao","programmer-error"],"backgroundTag":null,"analyzedSha":"2d3ccc6ba2ce98c3781bfc441bb3e884f072774f","analyzedAt":"2026-08-15T16:09:14.432Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}