{"record":{"id":"24f6481fccef8aa5","repo":"siyuan-note/siyuan","slug":"global-attachment-s-already-exists","errorCode":null,"errorMessage":"global attachment [%s] already exists","messagePattern":"global attachment \\[(.+?)\\] already exists","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"kernel/model/import_obsidian.go","lineNumber":1756,"sourceCode":"\t\tmarkObsidianNotebookIncomplete(boxID, notebookName)\n\t\tfailObsidianTask(taskID, \"writing\", err, result)\n\t\tremoveObsidianTemp(taskID)\n\t\treturn\n\t}\n\tif err = os.MkdirAll(filepath.Join(util.DataDir, \"assets\"), 0755); err != nil {\n\t\tresult.Incomplete = true\n\t\tmarkObsidianNotebookIncomplete(boxID, notebookName)\n\t\tfailObsidianTask(taskID, \"writing\", err, result)\n\t\tremoveObsidianTemp(taskID)\n\t\treturn\n\t}\n\n\tfor _, key := range assetKeys {\n\t\tasset := vault.ImportAssets[key]\n\t\tsource := filepath.Join(assetsTemp, asset.FinalName)\n\t\tdestination := filepath.Join(util.DataDir, \"assets\", asset.FinalName)\n\t\tif filelock.IsExist(destination) {\n\t\t\terr = fmt.Errorf(\"global attachment [%s] already exists\", asset.FinalName)\n\t\t} else {\n\t\t\terr = filelock.Rename(source, destination)\n\t\t}\n\t\tif err != nil {\n\t\t\tresult.Incomplete = true\n\t\t\tmarkObsidianNotebookIncomplete(boxID, notebookName)\n\t\t\tfailObsidianTask(taskID, \"writing\", err, result)\n\t\t\tremoveObsidianTemp(taskID)\n\t\t\treturn\n\t\t}\n\t}\n\n\tupdateObsidianTask(taskID, ObsidianTaskStateIndexing, 95, \"Indexing notebook\")\n\texisted, err := Mount(boxID)\n\tif err != nil {\n\t\tresult.Incomplete = true\n\t\tmarkObsidianNotebookIncomplete(boxID, notebookName)\n\t\tfailObsidianTask(taskID, \"indexing\", err, result)","sourceCodeStart":1738,"sourceCodeEnd":1774,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/import_obsidian.go#L1738-L1774","documentation":"Raised during the final move of staged attachments into the workspace's global assets folder (data/assets). If a file with the same final name already exists there, the import does not overwrite it; instead it marks the result incomplete and records this conflict error so the notebook is flagged as needing manual attention.","triggerScenarios":"filelock.IsExist(destination) is true for filepath.Join(util.DataDir, \"assets\", asset.FinalName) — an attachment with an identical resolved filename was imported (by this or a previous import) before the rename step runs.","commonSituations":"Re-importing the same vault (or two vaults containing identically named images like 'image.png') into the same workspace; name-collision resolution during transformation produced a FinalName that already exists from an earlier partial import.","solutions":["Inspect data/assets for the reported FinalName; if it is from a prior import of the same vault, delete the leftover imported notebook and assets, then re-import cleanly","If the collision is with unrelated content, rename the source attachment in the vault (or let the importer generate a fresh unique name) and re-import","Treat the imported notebook as incomplete: verify which attachments are missing and copy the conflicting file manually if content differs"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const fs = require('fs');\nfunction assertNoAssetCollisions(dataDir, finalNames) {\n  const assetsDir = require('path').join(dataDir, 'assets');\n  const clashes = finalNames.filter(n => fs.existsSync(require('path').join(assetsDir, n)));\n  if (clashes.length) throw new Error('will collide: ' + clashes.join(', '));\n}","typeGuard":null,"tryCatchPattern":"try { await apiImportObsidian(vaultPath); }\ncatch (e) {\n  if (/already exists/.test(e.msg)) {\n    // inspect data/assets/<name>; remove stale files from a previous import or rename source asset, retry\n  }\n}","preventionTips":["Clean up leftover notebooks/assets from earlier failed imports before re-importing","Avoid importing multiple vaults containing identically named attachments into one workspace","Rename generic attachment names (image.png) in the vault beforehand","Check result.Incomplete after any import"],"tags":["file-already-exists","obsidian-import","assets"],"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"}