{"record":{"id":"f8ef147435c8feb4","repo":"angular/angular","slug":"duplicate-binding-name","errorCode":"DUPLICATE_BINDING_NAME","errorMessage":"Input '${bindingPropertyName}' is bound to both '${firstMember.name}' and '${member.name}'.","messagePattern":"Input '(.+?)' is bound to both '(.+?)' and '(.+?)'\\.","errorType":"exception","errorClass":"FatalDiagnosticError","httpStatus":null,"severity":"error","filePath":"packages/compiler-cli/src/ngtsc/annotations/directive/src/shared.ts","lineNumber":1452,"sourceCode":"    const inputMapping = tryParseInputFieldMapping(\n      clazz,\n      member,\n      evaluator,\n      reflector,\n      importTracker,\n      isCore,\n      refEmitter,\n      compilationMode,\n      emitDeclarationOnly,\n    );\n    if (inputMapping === null) {\n      continue;\n    }\n\n    const bindingPropertyName = inputMapping.bindingPropertyName;\n    if (bindings.has(bindingPropertyName)) {\n      const firstMember = bindings.get(bindingPropertyName)!;\n      throw new FatalDiagnosticError(\n        ErrorCode.DUPLICATE_BINDING_NAME,\n        member.node ?? clazz,\n        `Input '${bindingPropertyName}' is bound to both '${firstMember.name}' and '${member.name}'.`,\n        [makeRelatedInformation(firstMember.node ?? clazz, `The first binding is declared here.`)],\n      );\n    }\n    bindings.set(bindingPropertyName, member);\n\n    if (member.isStatic) {\n      throw new FatalDiagnosticError(\n        ErrorCode.INCORRECTLY_DECLARED_ON_STATIC_MEMBER,\n        member.node ?? clazz,\n        `Input \"${member.name}\" is incorrectly declared as static member of \"${clazz.name.text}\".`,\n      );\n    }\n\n    // Validate that signal inputs are not accidentally declared in the `inputs` metadata.\n    if (inputMapping.isSignal && Object.hasOwn(inputsFromClassDecorator, classPropertyName)) {","sourceCodeStart":1434,"sourceCodeEnd":1470,"githubUrl":"https://github.com/angular/angular/blob/51cb07e98081ab7e4e84a9e0949266a8e19cca84/packages/compiler-cli/src/ngtsc/annotations/directive/src/shared.ts#L1434-L1470","documentation":"Thrown when two inputs in the same directive/component resolve to the same binding property name. After each member's InputMapping is computed, its bindingPropertyName (alias if given, else the member name) is tracked in a Map; a repeat raises DUPLICATE_BINDING_NAME with `Input 'x' is bound to both 'first' and 'second'`, plus related information pointing at the first declaration. Ambiguous template bindings cannot be emitted, so compilation stops.","triggerScenarios":"`@Input('label') labelA = ''; @Input('label') labelB = '';` — or an alias colliding with another member's plain name: `@Input() label = ''; @Input('label') other = '';`.","commonSituations":"Copy-pasted aliased inputs; renames that accidentally create alias/name collisions; entries in the class-decorator `inputs: ['alias: prop']` metadata array overlapping a decorated member's name; merging two components.","solutions":["Make every binding property name unique — rename or drop one alias: `@Input('firstLabel') firstName` / `@Input('lastLabel') lastName`.","Check the `inputs: ['alias: prop']` metadata array for entries duplicating a decorated member's name or alias.","Use the related-information location in the diagnostic to find the first binding and fix the second."],"exampleFix":"// before\n@Input('label') firstName = '';\n@Input('label') lastName = '';\n\n// after\n@Input('firstLabel') firstName = '';\n@Input('lastLabel') lastName = '';","handlingStrategy":"validation","validationCode":"// collect input binding names per class and fail on duplicates\nfunction checkDuplicateInputAliases(members: {prop: string; alias?: string}[]) {\n  const seen = new Map<string, string>();\n  for (const m of members) {\n    const binding = m.alias ?? m.prop;\n    if (seen.has(binding)) {\n      throw new Error(`Input '${binding}' bound to both '${seen.get(binding)}' and '${m.prop}'`);\n    }\n    seen.set(binding, m.prop);\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep a per-class inventory of input binding names (aliases included) when adding or renaming inputs.","Cross-check the `inputs: ['alias: prop']` metadata array against decorated members.","Use the diagnostic's related information to jump to the first conflicting binding."],"tags":["angular","compiler-cli","input","duplicate-binding","alias"],"backgroundTag":"angular-duplicate-input-binding","analyzedSha":"51cb07e98081ab7e4e84a9e0949266a8e19cca84","analyzedAt":"2026-08-22T07:04:54.531Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}