{"record":{"id":"a2d689a93c6c1e9b","repo":"angular/components","slug":"xposition-value-must-be-either-before-or-after","errorCode":null,"errorMessage":"xPosition value must be either 'before' or after'.\n      Example: <mat-menu xPosition=\"before\" #menu=\"matMenu\"></mat-menu>","messagePattern":"xPosition value must be either 'before' or after'\\.\n      Example: <mat-menu xPosition=\"before\" #menu=\"matMenu\"></mat-menu>","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/material/menu/menu-errors.ts","lineNumber":15,"sourceCode":"/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\n/**\n * Throws an exception for the case when menu's x-position value isn't valid.\n * In other words, it doesn't match 'before' or 'after'.\n * @docs-private\n */\nexport function throwMatMenuInvalidPositionX() {\n  throw Error(`xPosition value must be either 'before' or after'.\n      Example: <mat-menu xPosition=\"before\" #menu=\"matMenu\"></mat-menu>`);\n}\n\n/**\n * Throws an exception for the case when menu's y-position value isn't valid.\n * In other words, it doesn't match 'above' or 'below'.\n * @docs-private\n */\nexport function throwMatMenuInvalidPositionY() {\n  throw Error(`yPosition value must be either 'above' or below'.\n      Example: <mat-menu yPosition=\"above\" #menu=\"matMenu\"></mat-menu>`);\n}\n\n/**\n * Throws an exception for the case when a menu is assigned\n * to a trigger that is placed inside the same menu.\n * @docs-private\n */","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/angular/components/blob/0411926e7d8ae06b32236ec1048a888cfad5abf2/src/material/menu/menu-errors.ts#L1-L33","documentation":"MatMenu validates the xPosition input against 'before' | 'after'. Any other value makes the positioning math invalid, so the xPosition setter calls throwMatMenuInvalidPositionX, whose message (noting the missing opening quote on \"after'\") shows usage.","triggerScenarios":"Setting <mat-menu xPosition=\"left\">, xPosition=\"right\", or a bound [xPosition]=\"expr\" where expr is null/undefined/typo.","commonSituations":"Typing CSS-like values ('left'/'right') instead of Material's vocabulary; binding from config data that defaults to null before load; renaming refactor that introduced casing mismatch ('Before').","solutions":["Use xPosition=\"before\" or xPosition=\"after\" literally.","For bound values, constrain the type: xPosition: 'before' | 'after' and guard config defaults (xPosition ?? 'after').","Validate external config before passing into the template."],"exampleFix":"// before\n<mat-menu [xPosition]=\"menu.x\"></mat-menu> <!-- menu.x = 'left' -->\n// after\n<mat-menu [xPosition]=\"menu.x === 'left' ? 'before' : 'after'\"></mat-menu>","handlingStrategy":"validation","validationCode":"type MenuXPosition = 'before' | 'after';\nfunction isXPosition(v: unknown): v is MenuXPosition {\n  return v === 'before' || v === 'after';\n}\nconst x = isXPosition(config.x) ? config.x : 'after';\n// template: <mat-menu [xPosition]=\"x\">","typeGuard":"function isMenuXPosition(v: unknown): v is 'before' | 'after' {\n  return v === 'before' || v === 'after';\n}","tryCatchPattern":"try {\n  menu.xPosition = config.x as 'before' | 'after';\n} catch (e) {\n  if ((e as Error).message.includes('xPosition value must be')) {\n    console.warn(`Invalid xPosition \"${config.x}\", defaulting to 'after'`);\n    menu.xPosition = 'after';\n  } else { throw e; }\n}","preventionTips":["Use only 'before'/'after' — not 'left'/'right'","Provide defaults for async-bound values: config.x ?? 'after'","Type config fields as 'before' | 'after' so TS rejects invalid values"],"tags":["angular-material","mat-menu","invalid-input"],"backgroundTag":"invalid-position-input","analyzedSha":"0411926e7d8ae06b32236ec1048a888cfad5abf2","analyzedAt":"2026-08-31T11:58:23.400Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}