{"record":{"id":"d6491879f94618c5","repo":"derailed/k9s","slug":"expecting-a-job-runner-resource-for-q","errorCode":null,"errorMessage":"expecting a job runner resource for %q","messagePattern":"expecting a job runner resource for %q","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/view/cronjob.go","lineNumber":106,"sourceCode":"func (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\n}\n\nfunc (c *CronJob) toggleSuspendCmd(evt *tcell.EventKey) *tcell.EventKey {\n\ttable := c.GetTable()\n\tsel := table.GetSelectedItem()","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/derailed/k9s/blob/2d3ccc6ba2ce98c3781bfc441bb3e884f072774f/internal/view/cronjob.go#L88-L124","documentation":"Thrown after the user confirms the 'Trigger CronJobs' dialog: k9s looks up the DAO via dao.AccessorFor(c.App().factory, c.GVR()) and type-asserts it to dao.Runnable (the interface exposing Run(fqn)). If the accessor registered for the current GVR does not implement Runnable, the assertion with ok-form fails and this error is flashed. It is an internal invariant: the trigger action is only valid on resources whose DAO can create jobs (normally the CronJob DAO).","triggerScenarios":"Pressing the trigger key on the CronJob view and confirming the dialog while c.GVR() maps to a DAO that lacks a Run method — e.g. a custom plugin/CRD view that reuses the CronJob viewer, or a k9s build where the internal dao and view packages are out of sync (recompiled plugin against a different k9s version).","commonSituations":"Custom views (views.yaml aliases) binding the CronJob browser to another GVR; third-party plugins replacing the accessor for batch/cronjobs; version skew between a locally built k9s and vendored internal packages.","solutions":["Confirm you are on the stock CronJob viewer (:batch:cronjobs or :v1:cronjobs) when triggering","Check views.yaml / plugin config for aliases that rebind the CronJob viewer to a different GVR","Rebuild/reinstall k9s so internal/view and internal/dao come from the same release (stale mixed binaries cause this)","If it reproduces on plain cronjobs with stock k9s, file an issue with the GVR string shown in the message"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func supportsRun(res dao.Resource) bool {\n    _, ok := res.(dao.Runnable)\n    return ok\n}\n\n// before showing the trigger dialog:\nres, err := dao.AccessorFor(c.App().factory, c.GVR())\nif err != nil || !supportsRun(res) {\n    c.App().Flash().Errf(\"trigger is only available for runnable resources (cronjobs)\")\n    return\n}","tryCatchPattern":null,"preventionTips":["Only bind the CronJob viewer/trigger action to GVRs whose DAO implements dao.Runnable","When writing plugins, type-assert accessors with the ok form and degrade gracefully instead of assuming the interface","Keep internal dao and view packages from the same k9s release when building from source"],"tags":["kubernetes","k9s","cronjob","type-assertion","dao"],"backgroundTag":null,"analyzedSha":"2d3ccc6ba2ce98c3781bfc441bb3e884f072774f","analyzedAt":"2026-08-15T16:09:14.432Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}