{"record":{"id":"692a14dfb2da7e29","repo":"DayuanJiang/next-ai-draw-io","slug":"page-id-id-already-exists","errorCode":null,"errorMessage":"Page id \"${id}\" already exists","messagePattern":"Page id \"(.+?)\" already exists","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/mcp-server/src/pages.ts","lineNumber":238,"sourceCode":" * Append a new <diagram> to the mxfile doc. The new page's model defaults to\n * an empty <mxGraphModel><root><mxCell id=\"0\"/><mxCell id=\"1\" parent=\"0\"/></root></mxGraphModel>.\n *\n * `opts.xml` must be a BARE <mxGraphModel> — passing a full <mxfile> would\n * end up nested inside <diagram>, which is malformed. We reject the mxfile\n * shape explicitly and strip any <?xml ?> declaration (only valid at\n * document start, never inside <diagram>).\n *\n * Returns the new PageInfo. Throws if the requested id collides or the xml\n * shape is wrong.\n */\nexport function addPageToDoc(\n    doc: Document,\n    opts: { id?: string; name?: string; xml?: string } = {},\n): PageInfo {\n    const existing = listPagesFromDoc(doc)\n    const id = opts.id || generatePageId()\n    if (existing.some((p) => p.id === id)) {\n        throw new Error(`Page id \"${id}\" already exists`)\n    }\n    const name = opts.name || `Page-${existing.length + 1}`\n\n    let inner: string\n    if (opts.xml?.trim()) {\n        const trimmed = stripXmlDeclaration(opts.xml.trim())\n        if (isMxFile(trimmed)) {\n            throw new Error(\n                \"addPageToDoc: opts.xml must be a bare <mxGraphModel>; received a full <mxfile>. Extract the target diagram's <mxGraphModel> first.\",\n            )\n        }\n        if (!isMxGraphModel(trimmed)) {\n            throw new Error(\n                \"addPageToDoc: opts.xml must be a bare <mxGraphModel>.\",\n            )\n        }\n        inner = trimmed\n    } else {","sourceCodeStart":220,"sourceCodeEnd":256,"githubUrl":"https://github.com/DayuanJiang/next-ai-draw-io/blob/155ef4f7acd29c9d46fb6fc35c92e6e6955a6ce1/packages/mcp-server/src/pages.ts#L220-L256","documentation":"addPageToDoc refuses to create a page whose id collides with an existing page in the same document. Page ids must be unique inside an <mxfile> because draw.io addresses pages by id for navigation and links. The check compares opts.id against listPagesFromDoc(doc).","triggerScenarios":"Calling addPageToDoc(doc, { id: 'page-1' }) when a page with id 'page-1' already exists; using a fixed/hardcoded id in a loop; re-running a script against a document it already mutated.","commonSituations":"Import scripts that copy pages from one file to another preserving ids; idempotent-looking scripts run twice; deterministic id generation (e.g. slug of page name) colliding with existing pages.","solutions":["Omit opts.id and let generatePageId() assign a unique id","If the id matters, check first: listPagesFromDoc(doc).some(p => p.id === myId) and skip or use a suffix","If importing pages, prefix or remap ids to avoid collisions","If the script may re-run, make it idempotent by checking for the page before adding"],"exampleFix":"// before\naddPageToDoc(doc, { id: 'spec', name: 'Spec' }) // throws if 'spec' exists\n\n// after\nif (!listPagesFromDoc(doc).some(p => p.id === 'spec')) {\n  addPageToDoc(doc, { id: 'spec', name: 'Spec' })\n}","handlingStrategy":"type-guard","validationCode":"import { listPagesFromDoc, addPageToDoc } from './pages'\nconst ids = new Set(listPagesFromDoc(doc).map(p => p.id))\nif (ids.has(wantedId)) throw new Error(`page id ${wantedId} taken; choose another`)","typeGuard":"function pageIdAvailable(doc: Document, id: string): boolean {\n  return !listPagesFromDoc(doc).some(p => p.id === id)\n}","tryCatchPattern":"try { addPageToDoc(doc, { id }) } catch (e) { if ((e as Error).message.includes('already exists')) addPageToDoc(doc, { id: `${id}-${Date.now()}` }) else throw e }","preventionTips":["Omit id to use generated unique ids","Make import scripts idempotent: check-then-add","Remap/prefix ids when copying pages between files"],"tags":["drawio","duplicate-id","pages","validation"],"backgroundTag":"duplicate-entity-id","analyzedSha":"155ef4f7acd29c9d46fb6fc35c92e6e6955a6ce1","analyzedAt":"2026-08-27T11:40:38.297Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}