{"record":{"id":"cf1e70d7f7db64bf","repo":"angular/components","slug":"a-drawer-was-already-declared-for-position-pos","errorCode":null,"errorMessage":"A drawer was already declared for 'position=\"${position}\"'","messagePattern":"A drawer was already declared for 'position=\"(.+?)\"'","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/material/sidenav/drawer.ts","lineNumber":55,"sourceCode":"  OnDestroy,\n  Output,\n  QueryList,\n  Renderer2,\n  ViewChild,\n  ViewEncapsulation,\n  DOCUMENT,\n  signal,\n} from '@angular/core';\nimport {merge, Observable, Subject} from 'rxjs';\nimport {debounceTime, delay, filter, map, mapTo, startWith, take, takeUntil} from 'rxjs/operators';\nimport {_animationsDisabled} from '../core';\n\n/**\n * Throws an exception when two MatDrawer are matching the same position.\n * @docs-private\n */\nexport function throwMatDuplicatedDrawerError(position: string) {\n  throw Error(`A drawer was already declared for 'position=\"${position}\"'`);\n}\n\n/** Options for where to set focus to automatically on dialog open */\nexport type AutoFocusTarget = 'dialog' | 'first-tabbable' | 'first-heading';\n\n/** Result of the toggle promise that indicates the state of the drawer. */\nexport type MatDrawerToggleResult = 'open' | 'close';\n\n/** Drawer and SideNav display modes. */\nexport type MatDrawerMode = 'over' | 'push' | 'side';\n\n/** Configures whether drawers should use auto sizing by default. */\nexport const MAT_DRAWER_DEFAULT_AUTOSIZE = new InjectionToken<boolean>(\n  'MAT_DRAWER_DEFAULT_AUTOSIZE',\n  {\n    providedIn: 'root',\n    factory: () => false,\n  },","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/angular/components/blob/0411926e7d8ae06b32236ec1048a888cfad5abf2/src/material/sidenav/drawer.ts#L37-L73","documentation":"MatDrawerContainer validates its drawers in `_validateDrawers` and throws via `throwMatDuplicatedDrawerError` when two `<mat-drawer>` elements declare the same `position` ('start' or 'end'). Each side of a container may hold at most one drawer. It is a template-configuration error caught immediately at render time.","triggerScenarios":"Declaring two `<mat-drawer position=\"start\">` (or two 'end') inside one `<mat-drawer-container>`, or binding `position` to a property whose value collides with another drawer's.","commonSituations":"Copy-pasting a drawer block in a template and forgetting to change its position; conditional rendering where two drawers briefly both compute the same position; refactoring from two containers into one.","solutions":["Give each drawer in the container a unique position: one 'start', one 'end'.","Move the extra drawer into its own `<mat-drawer-container>` if two same-side drawers are needed.","If position is bound with `[position]`, ensure the bound values cannot collide at runtime.","Wrap drawer in `<mat-drawer-content>` usage checks and re-render after fixing the template."],"exampleFix":"// before\n<mat-drawer-container>\n  <mat-drawer position=\"start\">Menu</mat-drawer>\n  <mat-drawer position=\"start\">Filters</mat-drawer>\n</mat-drawer-container>\n// after\n<mat-drawer-container>\n  <mat-drawer position=\"start\">Menu</mat-drawer>\n  <mat-drawer position=\"end\">Filters</mat-drawer>\n</mat-drawer-container>","handlingStrategy":"validation","validationCode":"// Template review guard: count drawers per position\nconst positions = Array.from(\n  document.querySelectorAll('mat-drawer')\n).map(d => d.getAttribute('ng-reflect-position'));\nconst dupes = positions.filter((p, i) => positions.indexOf(p) !== i);\nif (dupes.length) throw new Error('Duplicate drawer position: ' + dupes[0]);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["One 'start' and at most one 'end' drawer per container.","Avoid binding [position] to dynamic values that can collide.","Lint templates for repeated <mat-drawer> blocks after copy-paste."],"tags":["angular","material","template","configuration"],"backgroundTag":"duplicate-drawer-position","analyzedSha":"0411926e7d8ae06b32236ec1048a888cfad5abf2","analyzedAt":"2026-08-31T11:58:23.400Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}