{"record":{"id":"7fbe6f3ab6bd153a","repo":"siyuan-note/siyuan","slug":"please-configure-settings-export-pandoc-pat","errorCode":null,"errorMessage":"Please configure [Settings - Export - Pandoc - Path to Pandoc executable] first","messagePattern":"Please configure \\[Settings - Export - Pandoc - Path to Pandoc executable\\] first","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/export.go","lineNumber":1054,"sourceCode":"\t\tif footnotesDefBlock := tree.Root.ChildByType(ast.NodeFootnotesDefBlock); nil != footnotesDefBlock {\n\t\t\tfootnotesDefBlock.Unlink()\n\t\t}\n\t\treturn nil\n\t}); exportErr != nil {\n\t\tlogging.LogErrorf(\"export preview [%s] failed: %s\", id, exportErr)\n\t\treturn\n\t}\n\treturn\n}\n\nfunc ExportDocx(id, savePath string, removeAssets, merge bool, mergeHeadingOptions ...MergeHeadingOptions) (fullPath string, err error) {\n\terr = withExportReadLockByBlockID(id, func() error {\n\t\tpandocRuntime := util.GetPandocRuntime()\n\t\tif !util.IsValidPandocBin(pandocRuntime.BinPath) {\n\t\t\tutil.InitPandoc(Conf.Export.PandocBin)\n\t\t\tpandocRuntime = util.GetPandocRuntime()\n\t\t\tif !util.IsValidPandocBin(pandocRuntime.BinPath) {\n\t\t\t\treturn errors.New(Conf.Language(115))\n\t\t\t}\n\t\t}\n\n\t\ttmpDir := filepath.Join(util.TempDir, \"export\", gulu.Rand.String(7))\n\t\tif bt := getExportBlockTree(id); bt != nil && IsEncryptedBox(bt.BoxID) {\n\t\t\texportID, idErr := newManagedEncryptedExportID()\n\t\t\tif idErr != nil {\n\t\t\t\treturn idErr\n\t\t\t}\n\t\t\ttmpDir = filepath.Join(util.TempDir, \"export\", bt.BoxID, \"docx\", exportID)\n\t\t}\n\t\tif mkdirErr := os.MkdirAll(tmpDir, 0755); mkdirErr != nil {\n\t\t\treturn mkdirErr\n\t\t}\n\t\tdefer os.RemoveAll(tmpDir)\n\t\tname, content := ExportMarkdownHTML(id, tmpDir, true, merge, mergeHeadingOptions...)\n\t\tcontent = strings.ReplaceAll(content, \"  \\n\", \"<br>\\n\")\n","sourceCodeStart":1036,"sourceCodeEnd":1072,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/afa823b6b4e4f183511e0bc0a3be93caa94c7c97/kernel/model/export.go#L1036-L1072","documentation":"model.ExportDocx (POST /api/export/exportDocx) shells out to pandoc. It resolves the binary via util.GetPandocRuntime and validates it with util.IsValidPandocBin; if invalid it re-initializes from Conf.Export.PandocBin and re-checks, and if still invalid returns the localized error asking for Settings - Export - Pandoc - Path to Pandoc executable (Conf.Language(115)). No conversion is attempted without a working pandoc.","triggerScenarios":"POST /api/export/exportDocx when pandoc is not installed, Conf.Export.PandocBin points to a missing or non-executable file, or the binary exists but fails the validity invocation (wrong architecture, blocked by macOS Gatekeeper).","commonSituations":"Fresh installs without pandoc; Docker/minimal images; portable setups where the configured path went stale after an update; mis-entered paths with quotes or spaces; downloaded binaries lacking the exec bit on Linux.","solutions":["Install pandoc (winget/choco/brew/apt) or download the official release","Set the absolute binary path in Settings - Export - Pandoc - Path to Pandoc executable, or clear it to let the kernel auto-detect from PATH","Verify as the same user that runs the kernel: <path-to-pandoc> --version","On Linux chmod +x the binary; on macOS remove the quarantine attribute (xattr -d com.apple.quarantine <binary>) if Gatekeeper blocks it","Retry the export — the kernel re-inits pandoc from config on each call"],"exampleFix":"# before: ExportDocx -> \"Please configure [Settings - Export - Pandoc - Path to Pandoc executable] first\"\n\n# after: install, configure, retry\nbrew install pandoc   # or: choco install pandoc / apt install pandoc\n# Settings - Export - Pandoc - Path to Pandoc executable: /opt/homebrew/bin/pandoc\n# then retry POST /api/export/exportDocx","handlingStrategy":"validation","validationCode":"if !util.IsValidPandocBin(util.GetPandocRuntime().BinPath) {\n\tutil.InitPandoc(model.Conf.Export.PandocBin)\n\tif !util.IsValidPandocBin(util.GetPandocRuntime().BinPath) {\n\t\treturn errors.New(\"configure a valid pandoc binary before docx export\")\n\t}\n}\nfullPath, err := model.ExportDocx(id, savePath, false, false)","typeGuard":null,"tryCatchPattern":"if _, err := model.ExportDocx(id, savePath, false, false); err != nil {\n\tif err.Error() == model.Conf.Language(115) {\n\t\t// pandoc missing: prompt to install/configure, then let the user retry\n\t}\n}","preventionTips":["Validate pandoc at app or plugin startup, not at export time","Pin an absolute pandoc path for portable installs","Smoke-test the binary with --version after OS updates"],"tags":["pandoc","docx","export","configuration","external-tool"],"backgroundTag":"external-binary-not-found","analyzedSha":"afa823b6b4e4f183511e0bc0a3be93caa94c7c97","analyzedAt":"2026-08-18T17:04:10.865Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}