siyuan-note/siyuan · error

template source is too large

Error message

template source is too large

What it means

templateFileRevision computes a SHA-256 revision fingerprint of a template file or directory. For a regular file it reads the whole content into memory to hash it, but first rejects any file larger than maxTemplateSourceSize (8 MiB) so a single template cannot force the kernel to buffer an unbounded amount of data. The error means the template file exceeds the 8 MiB size cap, so no revision (and hence no save/move/delete that requires optimistic concurrency) can be computed for it.

Source

Thrown at kernel/model/template_manage.go:141

	h := sha256.New()
	if info.IsDir() {
		err = fs.WalkDir(root.FS(), p, func(name string, entry fs.DirEntry, walkErr error) error {
			if walkErr != nil {
				return walkErr
			}
			stat, statErr := entry.Info()
			if statErr != nil {
				return statErr
			}
			if stat.Mode()&os.ModeSymlink != 0 {
				return errors.New("template directory contains a symbolic link")
			}
			fmt.Fprintf(h, "%s\x00%d\x00%d\x00%d\n", name, stat.Size(), stat.ModTime().UnixNano(), stat.Mode())
			return nil
		})
	} else {
		if info.Size() > maxTemplateSourceSize {
			return "", errors.New("template source is too large")
		}
		var content []byte
		content, err = root.ReadFile(p)
		h.Write(content)
	}
	return fmt.Sprintf("%x", h.Sum(nil)), err
}

func readTemplateSource(root *os.Root, p string) (string, error) {
	info, err := root.Stat(p)
	if err != nil {
		return "", err
	}
	if !info.Mode().IsRegular() || info.Size() > maxTemplateSourceSize {
		return "", errors.New("invalid template source file")
	}
	content, err := root.ReadFile(p)
	if err != nil {

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Shrink or split the template file so it is under 8 MiB, e.g. move large assets out of the markdown into the assets folder and reference them
  2. If the file is not really a template, move it out of data/templates/ so it is not managed
  3. If the file legitimately needs to be large, recreate it as a template package (directory with template.json) — directory revisions only hash metadata, not content

Example fix

// oversized single template
data/templates/big-notes.md        (12 MB)
// after
 data/templates/big-notes/template.json
data/templates/big-notes/big-notes.md  (still read-capped, but revision hashing no longer buffers file content)
Defensive patterns

Strategy: validation

Validate before calling

const info = fs.statSync(path.join(dataDir, 'templates', p));
if (!info.isDirectory() && info.size > 8 * 1024 * 1024) {
  throw new Error('template exceeds 8 MiB cap; shrink or move it out of templates/');
}

Try / catch

try {
  await manageTemplateFiles({ action: 'read', path: p, revision: rev });
} catch (e) {
  if (String(e.message).includes('template source is too large')) {
    // surface a 'file too large to manage' message and offer to move the file out of templates/
  }
}

Prevention

When it happens

Trigger: Calling ManageTemplateFiles with any action other than 'list'/'mkdir' on an existing non-directory template whose on-disk size is > 8388608 bytes: the request first reaches templateFileRevision via the revision check (template_manage.go:269), so even 'read' on an oversized file fails here before readTemplateSource runs.

Common situations: A user pasted a huge log/dataset into a template and saved it externally; a file was dropped into data/templates/ by another tool or sync service and happens to be over 8 MiB; a .md was renamed from an export that embedded large base64 images.

Understand the failure class

Background: "File too large" / "file size exceeds limit" errors: why libraries cap file sizes and how to fix them — this error's family across 46 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/172b6c0adb710d11. Report an issue: GitHub.