{"record":{"id":"df5870dd837c5f7a","repo":"siyuan-note/siyuan","slug":"created-doc-path-s-already-exists","errorCode":null,"errorMessage":"created doc path [%s] already exists","messagePattern":"created doc path \\[(.+?)\\] already exists","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/transaction.go","lineNumber":2709,"sourceCode":"\t\t}\n\t\tif current := tx.trees[tree.ID]; nil != current {\n\t\t\torderedTrees = append(orderedTrees, current)\n\t\t\trestoredIDs[tree.ID] = struct{}{}\n\t\t}\n\t}\n\tfor id, tree := range tx.trees {\n\t\tif _, restored := restoredIDs[id]; !restored {\n\t\t\torderedTrees = append(orderedTrees, tree)\n\t\t}\n\t}\n\tfor _, tree := range orderedTrees {\n\t\tif _, restored := restoredIDs[tree.ID]; restored {\n\t\t\tbox := Conf.Box(tree.Box)\n\t\t\tif nil == box {\n\t\t\t\treturn ErrBoxNotFound\n\t\t\t}\n\t\t\tif box.Exist(tree.Path) {\n\t\t\t\treturn fmt.Errorf(\"created doc path [%s] already exists\", tree.Path)\n\t\t\t}\n\t\t\ttx.attemptedTemplateCreatedDocs[tree.ID] = tree\n\t\t}\n\t\twriteTransactionTree := tx.writeTransactionTree\n\t\tif nil == writeTransactionTree {\n\t\t\twriteTransactionTree = writeTreeUpsertQueue\n\t\t}\n\t\tif err = writeTransactionTree(tree); err != nil {\n\t\t\treturn\n\t\t}\n\n\t\tvar sources []any\n\t\tsources = append(sources, tx)\n\t\tutil.PushSaveDoc(tree.ID, \"tx\", sources)\n\n\t\tcheckUpsertInUserGuide(tree)\n\t}\n\tfor boxID, icon := range tx.boxIcons {","sourceCodeStart":2691,"sourceCodeEnd":2727,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/transaction.go#L2691-L2727","documentation":"When restoring documents that were created from a template (e.g. during redo or rollback bookkeeping), the kernel checks that the target path inside the notebook box does not already exist before writing. If a file already occupies tree.Path, writing would clobber an existing document, so the commit fails with this error naming the conflicting path.","triggerScenarios":"Committing a transaction where a restored/created doc's path already exists in the box (box.Exist(tree.Path) is true) — typically because the document was recreated with the same ID/path earlier, or a prior partial commit left the file behind.","commonSituations":"Undo followed by redo of template document creation where the first attempt's file was not cleaned up; the same template inserted twice producing the same path; sync restored a copy of the document while a local restore was pending.","solutions":["Delete or rename the existing document at the reported path, then retry the transaction","Refresh the document tree so the UI reflects the actual existing document and re-do the template creation into a fresh doc","Investigate leftover files from a failed prior transaction (compare data/<box>/.siyuan/ contents with the doc tree) and clean them up via the UI"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const exists = await fetchPost('/api/filetree/docExists', {box: boxId, path: docPath});\nif (exists.data) throw new Error('path already exists: ' + docPath);","typeGuard":null,"tryCatchPattern":"try {\n  await redoTemplateCreation(tx);\n} catch (e) {\n  if (/created doc path \\[.*\\] already exists/.test(String(e.message))) {\n    await reloadDocTree(); // adopt the existing doc instead of recreating it\n  } else { throw e; }\n}","preventionTips":["Complete undo before starting redo of the same template creation","Do not manually recreate documents with paths produced by pending transactions","Refresh the document tree after any failed or interrupted transaction to detect leftovers"],"tags":["transaction","templates","path-conflict"],"backgroundTag":"file-already-exists","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}