{"record":{"id":"bff530b590f77598","repo":"denoland/deno","slug":"visitor-name-of-plugin-id-errored","errorCode":null,"errorMessage":"Visitor \"${name}\" of plugin \"${id}\" errored","messagePattern":"Visitor \"(.+?)\" of plugin \"(.+?)\" errored","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"cli/js/40_lint.js","lineNumber":1285,"sourceCode":"          const key = selectors[j];\n\n          let info = bySelector.get(key);\n          if (info === undefined) {\n            info = { enter: NOOP, exit: NOOP };\n            bySelector.set(key, info);\n          }\n          const prevFn = isExit ? info.exit : info.enter;\n\n          /**\n           * @param {*} node\n           */\n          const wrapped = (node) => {\n            prevFn(node);\n\n            try {\n              fn(node);\n            } catch (err) {\n              throw new Error(`Visitor \"${name}\" of plugin \"${id}\" errored`, {\n                cause: err,\n              });\n            }\n          };\n\n          if (isExit) {\n            info.exit = wrapped;\n          } else {\n            info.enter = wrapped;\n          }\n        }\n      }\n\n      if (typeof rule.destroy === \"function\") {\n        const destroyFn = rule.destroy.bind(rule);\n        destroyFns.push(() => {\n          try {\n            destroyFn(ruleCtx);","sourceCodeStart":1267,"sourceCodeEnd":1303,"githubUrl":"https://github.com/denoland/deno/blob/89f33cbef296a2b287f323d42de54c871fa69c77/cli/js/40_lint.js#L1267-L1303","documentation":"Thrown at lint-run time in runPluginsForFile (cli/js/40_lint.js) when a rule's visitor callback raises. The linter wraps every enter/exit visitor so the error names the rule and plugin (\"Visitor \\\"<rule>\\\" of plugin \\\"<plugin>/<rule>\\\" errored\") and attaches the original exception as `cause`. This is a wrapper: the real bug is in your visitor code, retrievable via err.cause.","triggerScenarios":"Any exception inside a `create(ctx)` visitor function while traversing a file: calling a method on undefined (e.g. node.callee.name on a node without callee), accessing properties of a node type that doesn't have them, or throwing intentionally without wrapping. Fires per file visited, during `deno lint` on real source files (not at plugin load time).","commonSituations":"A visitor assumes a specific node shape (e.g. MemberExpression) but the selector also matched a different shape; a rule that reads node.parent or sibling nodes that can be null; rules tested only on simple files crashing on edge-case syntax (decorators, optional chaining, directives).","solutions":["Inspect err.cause (and its stack) — it points at the exact line in your visitor, not at this wrapper message","Narrow inside the visitor: check node.type / property existence before accessing, or tighten the selector so only matching shapes reach the callback","Reproduce with `deno lint` on the single file that triggered it, then add that file as a fixture for the rule"],"exampleFix":"// before\n\"CallExpression:exit\"(node) {\n  reportIfUpperCase(node.callee.name);\n},\n\n// after\n\"CallExpression:exit\"(node) {\n  if (node.callee.type !== \"Identifier\") return;\n  reportIfUpperCase(node.callee.name);\n},","handlingStrategy":"try-catch","validationCode":"// smoke-test the plugin in CI: lint a fixture that exercises every visitor key\n// $ deno lint --config deno.json ./plugin_tests/fixtures/edge_cases.ts","typeGuard":null,"tryCatchPattern":"try {\n  await runLint(fixtures); // deno lint over representative files\n} catch (err) {\n  // the wrapper names the rule; err.cause holds the real stack\n  if (err instanceof Error && /Visitor \".+\" of plugin \".+\" errored/.test(err.message)) {\n    console.error(\"rule bug:\", err.cause ?? err);\n  }\n  throw err;\n}","preventionTips":["Validate node shape (node.type, property existence) at the top of every visitor before deep access","Keep a fixture corpus covering edge-case syntax for each rule and lint it in CI","Never let a visitor throw deliberately for control flow — use ctx.report"],"tags":["lint","plugin","visitor","runtime-error","ast"],"backgroundTag":null,"analyzedSha":"89f33cbef296a2b287f323d42de54c871fa69c77","analyzedAt":"2026-08-16T07:54:21.310Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}