siyuan-note/siyuan · error

Conf.Language(115) (Pandoc binary invalid)

Error message

Conf.Language(115) (Pandoc binary invalid)

What it means

ExportDocx (kernel/model/export.go:1105) requires a working Pandoc binary. It checks util.IsValidPandocBin; if invalid it attempts util.InitPandoc(Conf.Export.PandocBin) once more, and if the binary is still invalid it returns the localized message Conf.Language(115): 'Please configure [Settings - Export - Pandoc - Path to Pandoc executable] first'.

Source

Thrown at kernel/model/export.go:1105

		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 8641553a1f)

Solutions

  1. Install Pandoc and set the correct executable path in Settings - Export - Pandoc - Path to Pandoc executable.
  2. Set Conf.Export.PandocBin in the configuration to the absolute pandoc binary path and retry.
  3. Verify the configured path with util.IsValidPandocBin-equivalent: run '<path> --version' on the host.
  4. On Docker, use an image that bundles Pandoc or mount the binary into the container and configure its path.

Example fix

// before (config)
"PandocBin": ""
// after
"PandocBin": "/usr/bin/pandoc"
Defensive patterns

Strategy: validation

Validate before calling

const conf = await fetchPost('/api/conf/getConf');
const bin = conf.data.conf.export.pandocBin;
// verify the configured binary exists and runs before exporting
if (!bin) throw new Error('Configure Pandoc path in Settings - Export first');

Try / catch

try {
  await exportDocx(payload);
} catch (e) {
  if (String(e.msg).includes('Pandoc')) {
    await promptUserToConfigurePandoc();
  }
}

Prevention

When it happens

Trigger: Calling the docx export API (/api/export/exportDocx) when the Pandoc executable path is unset, points to a non-existent file, or the binary is not a valid Pandoc executable.

Common situations: Fresh SiYuan install without Pandoc installed; Pandoc removed or upgraded to a path not configured in Settings - Export - Pandoc; wrong path typed into the Pandoc bin setting; container image lacking the Pandoc dependency.

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@8641553a1f (2026-09-11). Data as JSON: /api/errors/e6c26f6b676f703c. Report an issue: GitHub.