{"record":{"id":"312430294c3dd00e","repo":"angular/components","slug":"matmenutriggerfor-menu-cannot-contain-its-own-tri","errorCode":null,"errorMessage":"matMenuTriggerFor: menu cannot contain its own trigger. Assign a menu that is not a parent of the trigger or move the trigger outside of the menu.","messagePattern":"matMenuTriggerFor: menu cannot contain its own trigger\\. Assign a menu that is not a parent of the trigger or move the trigger outside of the menu\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/material/menu/menu-errors.ts","lineNumber":35,"sourceCode":"}\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 */\nexport function throwMatMenuRecursiveError() {\n  throw Error(\n    `matMenuTriggerFor: menu cannot contain its own trigger. Assign a menu that is ` +\n      `not a parent of the trigger or move the trigger outside of the menu.`,\n  );\n}\n","sourceCodeStart":17,"sourceCodeEnd":40,"githubUrl":"https://github.com/angular/components/blob/0411926e7d8ae06b32236ec1048a888cfad5abf2/src/material/menu/menu-errors.ts#L17-L40","documentation":"A matMenuTrigger's menu must not be a DOM ancestor of the trigger itself; that would nest a trigger inside its own content, which the CDK overlay/menu wiring cannot represent. When the _menu setter detects the trigger element is inside the assigned menu content, it calls throwMatMenuRecursiveError.","triggerScenarios":"Placing a button with [matMenuTriggerFor]=\"menu\" inside a <mat-menu> that references that same menu (or an ancestor menu) as its content — e.g. building nested menus by reusing one menu instance for parent and child.","commonSituations":"Attempting multi-level cascading menus with a single shared menu component; recursive template components where each level declares trigger+menu with the same reference; moving a trigger into a menu panel during refactors.","solutions":["Move the trigger outside the <mat-menu> content and attach it via matMenuTriggerFor.","For cascading submenus, use the dedicated MatMenu nested-menu pattern: place the child trigger inside the parent menu and point it at a DIFFERENT child menu (matMenuTriggerFor pointing to a separate mat-menu instance).","Never reuse one menu instance as both parent and child; create one mat-menu per level."],"exampleFix":"// before\n<mat-menu #menu=\"matMenu\">\n  <button mat-menu-item [matMenuTriggerFor]=\"menu\">Nested</button>\n</mat-menu>\n// after\n<mat-menu #parent=\"matMenu\">\n  <button mat-menu-item [matMenuTriggerFor]=\"child\">Nested</button>\n</mat-menu>\n<mat-menu #child=\"matMenu\">\n  <button mat-menu-item>Action</button>\n</mat-menu>\n<button [matMenuTriggerFor]=\"parent\">Open</button>","handlingStrategy":"validation","validationCode":"// Assert no trigger lives inside its own menu before rendering:\nconst menuEl = document.querySelector('mat-menu');\nconst recursive = menuEl &&\n  Array.from(menuEl.querySelectorAll('[matMenuTriggerFor]'))\n    .some(t => t.getAttribute('matMenuTriggerFor') === menuRef);\nif (recursive) {\n  throw new Error('Menu contains its own trigger; restructure nested menus');\n}","typeGuard":null,"tryCatchPattern":"try {\n  this.trigger.menu = candidateMenu;\n} catch (e) {\n  if ((e as Error).message.includes('menu cannot contain its own trigger')) {\n    console.error('Create a separate child mat-menu instance for nested levels');\n  } else { throw e; }\n}","preventionTips":["Give every nesting level its own #menu template reference variable","Never reuse a single menu instance for parent and child levels","Keep triggers outside <mat-menu> content unless building the documented nested-menu pattern pointing at a DIFFERENT child menu"],"tags":["angular-material","mat-menu","recursion","template-structure"],"backgroundTag":"recursive-menu-trigger","analyzedSha":"0411926e7d8ae06b32236ec1048a888cfad5abf2","analyzedAt":"2026-08-31T11:58:23.400Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}