{"record":{"id":"76e59982e82f91cd","repo":"gatsbyjs/gatsby","slug":"a-languageextension-needs-to-contain-language-an","errorCode":null,"errorMessage":"A languageExtension needs to contain 'language' and 'extend' or both and a 'definition'. Given config is not valid: ${JSON.stringify(languageExtension)}","messagePattern":"A languageExtension needs to contain 'language' and 'extend' or both and a 'definition'\\. Given config is not valid: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/gatsby-remark-prismjs/src/load-prism-language-extension.js","lineNumber":24,"sourceCode":"  // Create array of languageExtensions (if input is object)\n  languageExtensions = [].concat(languageExtensions)\n\n  languageExtensions.forEach(l => {\n    loadLanguageExtension(l)\n  })\n}\n\nconst loadLanguageExtension = languageExtension => {\n  if (!isObjectAndNotArray(languageExtension)) {\n    throw new Error(\n      `A languageExtension needs to be defined as an object. Given config is not valid: ${JSON.stringify(\n        languageExtension\n      )}`\n    )\n  }\n\n  if (!containsMandatoryProperties(languageExtension)) {\n    throw new Error(\n      `A languageExtension needs to contain 'language' and 'extend' or both and a 'definition'. Given config is not valid: ${JSON.stringify(\n        languageExtension\n      )}`\n    )\n  }\n\n  // If only 'extend' property is given, we extend the given extend language.\n  if (!languageExtension.language) {\n    languageExtension.language = languageExtension.extend\n  }\n\n  // To allow RegEx as 'string' in the config, we replace all strings with a regex object.\n  if (languageExtension.definition) {\n    languageExtension.definition = replaceStringWithRegex(\n      languageExtension.definition\n    )\n  }\n","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/gatsbyjs/gatsby/blob/8b06340921ffdf23125a365b9c9923690cb62ce6/packages/gatsby-remark-prismjs/src/load-prism-language-extension.js#L6-L42","documentation":"Thrown by load-prism-language-extension when a language extension object is missing mandatory properties. It must contain 'language' and/or 'extend' plus a 'definition' function/object. Without these, Prism cannot register or extend a grammar.","triggerScenarios":"containsMandatoryProperties(languageExtension) returns false because the object lacks 'language', 'extend', or 'definition'; e.g., an object with only 'language' but no 'definition'.","commonSituations":"User provides a partial config object (e.g., only language name without definition), or the definition is misspelled/omitted.","solutions":["Include 'definition' in every language extension object (a Prism grammar function or object).","Include at least 'extend' (the base language to extend) if not providing 'language'.","Follow the structure: { language: 'name', extend: 'base', definition: (Prism) => {...} }.","Refer to Prism's language extension docs for the expected definition format."],"exampleFix":"// before\n{ language: 'mylang' }\n// after\n{ language: 'mylang', extend: 'clike', definition: Prism => { Prism.languages.mylang = { ... } } }","handlingStrategy":"validation","validationCode":"// Validate mandatory properties\nfunction isValidExtension(ext: any): boolean {\n  const hasLangOrExtend = ext.language || ext.extend\n  const hasDefinition = ext.definition\n  return Boolean(hasLangOrExtend && hasDefinition)\n}\nconst invalid = extensions.filter(e => !isValidExtension(e))\nif (invalid.length) throw new Error('Extensions missing required properties')","typeGuard":"interface LanguageExtension {\n  language?: string\n  extend?: string\n  definition: unknown\n}\nconst isLanguageExtension = (val: unknown): val is LanguageExtension =>\n  typeof val === 'object' && val !== null &&\n  ('language' in val || 'extend' in val) && 'definition' in val","tryCatchPattern":null,"preventionTips":["Always include 'definition' and at least one of 'language' or 'extend' in extension configs.","Refer to Prism's extension documentation for the correct structure.","Validate the config object shape before passing it to the plugin."],"tags":["gatsby","prismjs","remark","configuration","validation"],"backgroundTag":null,"analyzedSha":"8b06340921ffdf23125a365b9c9923690cb62ce6","analyzedAt":"2026-08-13T02:36:21.405Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}