{"record":{"id":"a13a6587f6378a87","repo":"derailed/k9s","slug":"no-accessor-for-q","errorCode":null,"errorMessage":"no accessor for %q","messagePattern":"no accessor for %q","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/view/cronjob.go","lineNumber":101,"sourceCode":"\t\tui.KeyT: ui.NewKeyAction(\"Trigger\", c.triggerCmd, true),\n\t\tui.KeyS: ui.NewKeyAction(\"Suspend/Resume\", c.toggleSuspendCmd, true),\n\t})\n}\n\nfunc (c *CronJob) triggerCmd(evt *tcell.EventKey) *tcell.EventKey {\n\tfqns := c.GetTable().GetSelectedItems()\n\tif len(fqns) == 0 {\n\t\treturn evt\n\t}\n\tmsg := fmt.Sprintf(\"Trigger CronJob: %s?\", fqns[0])\n\tif len(fqns) > 1 {\n\t\tmsg = fmt.Sprintf(\"Trigger %d CronJobs?\", len(fqns))\n\t}\n\td := c.App().Styles.Dialog()\n\tdialog.ShowConfirm(&d, c.App().Content.Pages, \"Confirm Job Trigger\", msg, func() {\n\t\tres, err := dao.AccessorFor(c.App().factory, c.GVR())\n\t\tif err != nil {\n\t\t\tc.App().Flash().Err(fmt.Errorf(\"no accessor for %q\", c.GVR()))\n\t\t\treturn\n\t\t}\n\t\trunner, ok := res.(dao.Runnable)\n\t\tif !ok {\n\t\t\tc.App().Flash().Err(fmt.Errorf(\"expecting a job runner resource for %q\", c.GVR()))\n\t\t\treturn\n\t\t}\n\n\t\tfor _, fqn := range fqns {\n\t\t\tif err := runner.Run(fqn); err != nil {\n\t\t\t\tc.App().Flash().Errf(\"CronJob trigger failed for %s: %v\", fqn, err)\n\t\t\t} else {\n\t\t\t\tc.App().Flash().Infof(\"Triggered Job %s %s\", c.GVR(), fqn)\n\t\t\t}\n\t\t}\n\t}, func() {})\n\n\treturn nil","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/derailed/k9s/blob/2d3ccc6ba2ce98c3781bfc441bb3e884f072774f/internal/view/cronjob.go#L83-L119","documentation":"dao.AccessorFor(factory, gvr) failed for the CronJob GVR: the DAO layer could not produce an accessor, so the trigger-Job confirmation dialog aborts. The underlying error is discarded and replaced by this generic message — AccessorFor fails when no DAO is registered for the GVR or the factory/connection is not initialized. Note the real cause is never shown, which hides whether this is a registration gap or a connection problem.","triggerScenarios":"Triggering a CronJob (t key) when the factory has no active connection or the accessor registry lacks an entry for the cronjobs GVR — e.g. a fork/custom build that registers DAOs conditionally, batch API group not in discovery (very old clusters lacking cronjobs), or the confirm dialog racing a disconnect.","commonSituations":"Custom builds registering CronJob DAO only when the batch CRD is present; disconnected sessions where dialogs were opened before the drop; GVR string mismatches (batch/v1 vs batch/v1beta1 cronjobs) after a cluster upgrade; tests with a stub factory.","solutions":["Confirm standard cronjobs exist on the cluster: kubectl get cronjobs.batch works and appears in discovery.","Reconnect/restart the TUI so the DAO registry and factory initialize against the live cluster.","In custom builds, ensure the DAO for the CronJob GVR is registered before mounting the trigger binding.","Improve diagnostics: wrap and flash the underlying AccessorFor error instead of discarding it (see exampleFix)."],"exampleFix":"// before\nres, err := dao.AccessorFor(c.App().factory, c.GVR())\nif err != nil {\n    c.App().Flash().Err(fmt.Errorf(\"no accessor for %q\", c.GVR()))\n    return\n}\n\n// after: surface the real cause\nres, err := dao.AccessorFor(c.App().factory, c.GVR())\nif err != nil {\n    c.App().Flash().Err(fmt.Errorf(\"no accessor for %q: %w\", c.GVR(), err))\n    return\n}","handlingStrategy":"try-catch","validationCode":"if _, err := dao.AccessorFor(c.App().factory, c.GVR()); err != nil {\n    c.App().Flash().Err(fmt.Errorf(\"no accessor for %q: %w\", c.GVR(), err))\n    return\n}","typeGuard":"func accessorOK(f dao.Factory, gvr *client.GVR) bool {\n    _, err := dao.AccessorFor(f, gvr)\n    return err == nil\n}","tryCatchPattern":"res, err := dao.AccessorFor(c.App().factory, c.GVR())\nif err != nil {\n    // wrap so the real cause (no registration vs no connection) is visible\n    c.App().Flash().Err(fmt.Errorf(\"no accessor for %q: %w\", c.GVR(), err))\n    return\n}\nif runner, ok := res.(dao.Runnable); !ok {\n    c.App().Flash().Err(fmt.Errorf(\"resource %q cannot run jobs\", c.GVR()))\n    return\n}","preventionTips":["Register DAO accessors for every GVR that mounts action bindings like trigger.","Check factory/connection state before opening confirm dialogs that hit the DAO layer.","Always wrap and flash the underlying error; discarding err hides root cause.","Test custom builds with the confirm-dialog code path (not just list views) so registration gaps surface."],"tags":["go","kubernetes","cronjob","dao","error-handling"],"backgroundTag":null,"analyzedSha":"2d3ccc6ba2ce98c3781bfc441bb3e884f072774f","analyzedAt":"2026-08-15T16:09:14.432Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}