{"id":"e7a407567d465c22","repo":"babel/babel","slug":"the-decorators-plugin-requires-a-version-option","errorCode":null,"errorMessage":"The decorators plugin requires a 'version' option, whose value must be one of: '2023-11' or 'legacy'.","messagePattern":"The decorators plugin requires a 'version' option, whose value must be one of: '2023-11' or 'legacy'\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/babel-plugin-syntax-decorators/src/index.ts","lineNumber":13,"sourceCode":"import { declare } from \"@babel/helper-plugin-utils\";\n\nexport interface Options {\n  version?: \"legacy\" | \"2023-11\";\n}\n\nexport default declare((api, options: Options) => {\n  api.assertVersion(REQUIRED_VERSION(\"^7.0.0-0 || ^8.0.0\"));\n\n  const { version } = options;\n\n  if (version === undefined) {\n    throw new Error(\n      \"The decorators plugin requires a 'version' option, whose value must be one of: \" +\n        \"'2023-11' or 'legacy'.\",\n    );\n  }\n  if (version !== \"2023-11\" && version !== \"legacy\") {\n    throw new Error(\n      \"Unsupported decorators version: \" + JSON.stringify(version),\n    );\n  }\n  if (\"legacy\" in options) {\n    throw new Error(\n      `The .legacy option has been removed in Babel 8. Use .version: \"legacy\" instead.`,\n    );\n  }\n  if (\"decoratorsBeforeExport\" in options) {\n    throw new Error(\n      `The .decoratorsBeforeExport option has been removed in Babel 8. The decorators can come either before or after exports.`,\n    );","sourceCodeStart":1,"sourceCodeEnd":31,"githubUrl":"https://github.com/babel/babel/blob/06b6eae39da4ce0689fad64e2c48a6375a464208/packages/babel-plugin-syntax-decorators/src/index.ts#L1-L31","documentation":"Thrown by @babel/plugin-syntax-decorators (index.ts:13) when no `version` option is provided. Because decorators have two mutually incompatible spec drafts (the 2023-11 stage-3 spec and the legacy TC39 stage-1 spec), the parser cannot pick one implicitly — Babel 7.21+ made `version` mandatory to disambiguate parser behavior.","triggerScenarios":"Loading the decorators plugin as a bare string `\"@babel/plugin-proposal-decorators\"` or `\"@babel/plugin-syntax-decorators\"`, or as `[\"...\", {}]` with no `version` key. The check is `if (version === undefined)` at index.ts:12.","commonSituations":"Upgrading from Babel <7.21 where decorators defaulted to legacy, or copying a tutorial that predates the mandatory-version requirement. Also common when migrating TypeScript decorator configs to Babel without specifying the version.","solutions":["Add `{ version: \"2023-11\" }` for the current spec (recommended for new code), OR `{ version: \"legacy\" }` for TS/Aurelia/legacy Babel behavior.","Place the decorators plugin before @babel/plugin-transform-class-properties / transform-class-features in the plugins array (ordering matters for legacy mode)."],"exampleFix":"// before\nplugins: [\"@babel/plugin-proposal-decorators\"]\n// after\nplugins: [[\"@babel/plugin-proposal-decorators\", { version: \"2023-11\" }]]","handlingStrategy":"validation","validationCode":"const dec = config.plugins.find(p => Array.isArray(p) && /decorators$/.test(p[0]));\nconst opts = (dec && dec[1]) || {};\nif (opts.version !== \"2023-11\" && opts.version !== \"legacy\") {\n  throw new Error(\"decorators plugin needs version: '2023-11' or 'legacy'\");\n}","typeGuard":"function isValidDecoratorsVersion(v: unknown): v is \"2023-11\" | \"legacy\" {\n  return v === \"2023-11\" || v === \"legacy\";\n}","tryCatchPattern":null,"preventionTips":["Always pass the options object form `[\"plugin\", { version }]`, never the bare string form.","Pin a constant for the version so it can be changed in one place."],"tags":["babel","decorators","config","parser-option"],"analyzedSha":"06b6eae39da4ce0689fad64e2c48a6375a464208","analyzedAt":"2026-08-03T20:13:43.465Z","schemaVersion":2}