{"record":{"id":"7da669a73f08fbca","repo":"mermaid-js/mermaid","slug":"align-hint-direction-lists-id-more-than-on","errorCode":null,"errorMessage":"align ${hint.direction} lists [${id}] more than once","messagePattern":"align (.+?) lists \\[(.+?)\\] more than once","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/mermaid/src/diagrams/architecture/architectureDb.ts","lineNumber":277,"sourceCode":"  public getEdges(): ArchitectureEdge[] {\n    return this.edges;\n  }\n\n  public addLayoutHint(hint: ArchitectureLayoutHint): void {\n    if (hint.members.length < 2) {\n      throw new Error(\n        `An align directive requires at least two members; got ${hint.members.length}`\n      );\n    }\n    const seen = new Set<string>();\n    hint.members.forEach((id) => {\n      if (this.registeredIds.get(id) !== 'node') {\n        throw new Error(\n          `align ${hint.direction} references [${id}], which is not a service or junction`\n        );\n      }\n      if (seen.has(id)) {\n        throw new Error(`align ${hint.direction} lists [${id}] more than once`);\n      }\n      seen.add(id);\n    });\n    this.layoutHints.push(hint);\n  }\n\n  public getLayoutHints(): ArchitectureLayoutHint[] {\n    return this.layoutHints;\n  }\n\n  /**\n   * Returns the current diagram's adjacency list, spatial map, & group alignments.\n   * If they have not been created, run the algorithms to generate them.\n   * @returns\n   */\n  public getDataStructures() {\n    if (this.dataStructures === undefined) {\n      // Tracks how groups are aligned with one another. Generated while creating the adj list","sourceCodeStart":259,"sourceCodeEnd":295,"githubUrl":"https://github.com/mermaid-js/mermaid/blob/d93e9c88c01a599c062ee6a3f1462e3558ac6b90/packages/mermaid/src/diagrams/architecture/architectureDb.ts#L259-L295","documentation":"Thrown by ArchitectureDB.addLayoutHint when the same id appears more than once in hint.members. The DB walks the members array with a `seen` Set and rejects any repeat. An align chain with a duplicated node would create a degenerate (zero-length) constraint and confuse the layout engine.","triggerScenarios":"Calling db.addLayoutHint({ direction: 'row', members: ['a', 'a', 'b'] }). In DSL: `align row: a, a, b`.","commonSituations":"Copy-paste duplication in a DSL align chain; programmatic array construction that concatenates lists without dedup; refactors that merge two align directives naively.","solutions":["Remove duplicate ids so each member appears exactly once.","Dedupe the members array before calling addLayoutHint."],"exampleFix":"// before\ndb.addLayoutHint({ direction: 'row', members: ['a', 'a', 'b'] });\n// after\ndb.addLayoutHint({ direction: 'row', members: ['a', 'b'] });","handlingStrategy":"validation","validationCode":"function addLayoutHintSafe(db, hint) {\n  if (new Set(hint.members).size !== hint.members.length) {\n    throw new Error('align members contains duplicates');\n  }\n  db.addLayoutHint(hint);\n}","typeGuard":"const hasNoDuplicates = (arr) => new Set(arr).size === arr.length;","tryCatchPattern":null,"preventionTips":["Dedupe the members array before calling addLayoutHint.","Avoid merging align chains by simple concatenation."],"tags":["architecture","layout","align","duplicate"],"backgroundTag":null,"analyzedSha":"d93e9c88c01a599c062ee6a3f1462e3558ac6b90","analyzedAt":"2026-08-12T06:23:11.304Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}