{"id":"78f8b02e62e0e68c","repo":"eslint/eslint","slug":"context-report-called-with-a-suggest-option-with","errorCode":null,"errorMessage":"context.report() called with a suggest option with a messageId '${messageId}', but no messages were present in the rule metadata.","messagePattern":"context\\.report\\(\\) called with a suggest option with a messageId '(.+?)', but no messages were present in the rule metadata\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"lib/linter/file-report.js","lineNumber":402,"sourceCode":"\t}\n\n\treturn problem;\n}\n\n/**\n * Validates that suggestions are properly defined. Throws if an error is detected.\n * @param {Array<{ desc?: string, messageId?: string }>} suggest The incoming suggest data.\n * @param {Object} messages Object of meta messages for the rule.\n * @returns {void}\n */\nfunction validateSuggestions(suggest, messages) {\n\tif (suggest && Array.isArray(suggest)) {\n\t\tsuggest.forEach(suggestion => {\n\t\t\tif (suggestion.messageId) {\n\t\t\t\tconst { messageId } = suggestion;\n\n\t\t\t\tif (!messages) {\n\t\t\t\t\tthrow new TypeError(\n\t\t\t\t\t\t`context.report() called with a suggest option with a messageId '${messageId}', but no messages were present in the rule metadata.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (!messages[messageId]) {\n\t\t\t\t\tthrow new TypeError(\n\t\t\t\t\t\t`context.report() called with a suggest option with a messageId '${messageId}' which is not present in the 'messages' config: ${JSON.stringify(messages, null, 2)}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (suggestion.desc) {\n\t\t\t\t\tthrow new TypeError(\n\t\t\t\t\t\t\"context.report() called with a suggest option that defines both a 'messageId' and an 'desc'. Please only pass one.\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else if (!suggestion.desc) {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t\"context.report() called with a suggest option that doesn't have either a `desc` or `messageId`\",","sourceCodeStart":384,"sourceCodeEnd":420,"githubUrl":"https://github.com/eslint/eslint/blob/f131c034ad91bbf06bcbb6b5e931447a8e419a46/lib/linter/file-report.js#L384-L420","documentation":"Thrown by validateSuggestions() in file-report.js when a suggestion passed to context.report({ suggest: [...] }) uses a messageId, but the rule's meta.messages object is undefined or absent. ESLint needs meta.messages to resolve the messageId into human-readable suggestion text; without it the suggestion cannot be rendered. This is a TypeError indicating the rule author forgot to declare messages in the rule's metadata while referencing them in suggestions.","triggerScenarios":"A rule calls context.report({ suggest: [{ messageId: 'foo', fix(fixer) {...} }] }) but the rule object has no meta.messages property (or meta is entirely missing). The check at file-report.js:401 `if (!messages)` fires, where messages comes from ruleDefinition?.meta?.messages.","commonSituations":"Rule authors add suggestions referencing a messageId before adding the corresponding meta.messages block; porting a rule from another linter and forgetting the messages metadata; refactoring that moves messages out of meta accidentally; testing a custom rule in isolation without full metadata.","solutions":["Add a meta.messages object to the rule that includes the messageId used in the suggestion, e.g. meta: { messages: { foo: 'Replace with bar.' } }.","Verify the suggestion's messageId string exactly matches a key in meta.messages.","If you do not want to use messageId for the suggestion, use desc instead with an inline string."],"exampleFix":"// before\ncontext.report({\n  node,\n  message: 'Use bar',\n  suggest: [{ messageId: 'useBar', fix(fixer) { return fixer.replaceText(node, 'bar'); } }]\n});\n// rule meta has no messages\n\n// after\nmeta: {\n  messages: { useBar: 'Replace with bar.' }\n}\ncontext.report({\n  node,\n  suggest: [{ messageId: 'useBar', fix(fixer) { return fixer.replaceText(node, 'bar'); } }]\n});","handlingStrategy":"validation","validationCode":"function validateSuggestionMessages(rule, suggestions) {\n  const messages = rule?.meta?.messages;\n  for (const s of suggestions) {\n    if (s.messageId && (!messages || !(s.messageId in messages))) {\n      throw new Error(`Suggestion messageId '${s.messageId}' missing from meta.messages`);\n    }\n  }\n}\n// call before registering the rule","typeGuard":"function ruleHasMessagesForSuggestions(rule) {\n  const messages = rule?.meta?.messages;\n  return (\n    typeof rule === 'object' && rule !== null &&\n    (!rule.meta || !Array.isArray(rule.create?.({}) && []) || true) &&\n    (messages === undefined || (typeof messages === 'object' && messages !== null))\n  );\n}","tryCatchPattern":"try {\n  context.report({ node, suggest: [{ messageId: 'x', fix }] });\n} catch (e) {\n  if (e instanceof TypeError && /no messages were present/.test(e.message)) {\n    // fall back to inline desc\n    context.report({ node, suggest: [{ desc: 'x', fix }] });\n  } else { throw e; }\n}","preventionTips":["Always define meta.messages alongside any messageId usage in suggestions.","Write a rule authoring test that asserts every suggestion messageId has a matching meta.messages key.","Use the eslint-plugin/require-meta rule (from eslint-plugin-eslint-plugin) to enforce suggestion/message metadata."],"tags":["eslint","custom-rule","suggestions","messageid","rule-metadata"],"analyzedSha":"f131c034ad91bbf06bcbb6b5e931447a8e419a46","analyzedAt":"2026-08-03T19:53:24.025Z","schemaVersion":2}