siyuan-note/siyuan · error

Conf.Language(115)

Error message

Conf.Language(115)

What it means

ExportDocx (and other pandoc-based exports) require a working Pandoc executable. If util.GetPandocRuntime reports an invalid binary and re-initialization with Conf.Export.PandocBin still fails validation, the export aborts with i18n message 115: 'Please configure [Settings - Export - Pandoc - Path to Pandoc executable] first'.

Solutions

  1. Install Pandoc and set the correct path in Settings - Export - Pandoc - Path to Pandoc executable
  2. Set conf Export.PandocBin to a valid pandoc binary path programmatically
  3. Verify the binary exists and is executable (chmod +x on Unix) and matches the platform

Example fix

// before (conf)
{"export": {"pandocBin": "/opt/old-pandoc/pandoc"}} // deleted binary
// after
{"export": {"pandocBin": "/usr/bin/pandoc"}}
Defensive patterns

Strategy: fallback

Validate before calling

const bin = conf.export.pandocBin || defaultPandocPath;
if (!fs.existsSync(bin)) {
  notify('Configure [Settings - Export - Pandoc - Path to Pandoc executable] first');
  return;
}

Try / catch

try { await exportDocx(id, savePath); }
catch (e) {
  if (String(e).includes('Pandoc')) {
    promptUserToInstallOrConfigurePandoc();
  }
}

Prevention

When it happens

Trigger: Calling the docx/pandoc export API when no Pandoc binary is found at the configured or default path, or the configured path points to a missing/corrupt/non-executable file.

Common situations: Fresh install without Pandoc configured; Pandoc uninstalled or moved after configuration; wrong custom path set in Settings - Export - Pandoc; bundled Pandoc missing on a portable install.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/100edbda8d3539aa. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/export.go:1110

		return nil
	}); exportErr != nil {
		logging.LogErrorf("export preview [%s] failed: %s", id, exportErr)
		return
	}
	return
}

func ExportDocx(id, savePath string, removeAssets, merge bool, mergeHeadingOptions ...MergeHeadingOptions) (fullPath string, err error) {
	if err = prepareExportBlockAssets(id, merge); err != nil {
		return
	}
	err = withExportReadLockByBlockID(id, func() error {
		pandocRuntime := util.GetPandocRuntime()
		if !util.IsValidPandocBin(pandocRuntime.BinPath) {
			util.InitPandoc(Conf.Export.PandocBin)
			pandocRuntime = util.GetPandocRuntime()
			if !util.IsValidPandocBin(pandocRuntime.BinPath) {
				return errors.New(Conf.Language(115))
			}
		}

		tmpDir := filepath.Join(util.TempDir, "export", gulu.Rand.String(7))
		if bt := getExportBlockTree(id); bt != nil && IsEncryptedBox(bt.BoxID) {
			exportID, idErr := newManagedEncryptedExportID()
			if idErr != nil {
				return idErr
			}
			tmpDir = filepath.Join(util.TempDir, "export", bt.BoxID, "docx", exportID)
		}
		if mkdirErr := os.MkdirAll(tmpDir, 0755); mkdirErr != nil {
			return mkdirErr
		}
		defer os.RemoveAll(tmpDir)
		name, content, exportErr := exportMarkdownHTML(id, tmpDir, true, merge, mergeHeadingOptions...)
		if exportErr != nil {
			return exportErr

View on GitHub (pinned to 9f775e8a12)