siyuan-note/siyuan · error

skill source too large (limit 10MB)

Error message

skill source too large (limit 10MB)

What it means

Thrown by fetchBytes when the downloaded body exceeds maxSkillDownloadBytes (10 MiB). The reader deliberately reads one extra byte to detect the overflow, then rejects the payload. This caps skill source size to protect memory and disk.

Source

Thrown at kernel/util/skill.go:417

// fetchBytes 执行带大小限制的 GET
func fetchBytes(rawURL string) (data []byte, contentType string, err error) {
	resp, err := httpclient.NewBrowserRequest().Get(rawURL)
	if err != nil {
		return nil, "", errors.New("download failed: " + err.Error())
	}
	defer resp.Body.Close()

	if resp.StatusCode >= 400 {
		return nil, "", fmt.Errorf("download failed: HTTP %d", resp.StatusCode)
	}

	contentType = resp.Header.Get("Content-Type")
	body, err := io.ReadAll(io.LimitReader(resp.Body, maxSkillDownloadBytes+1))
	if err != nil {
		return nil, "", errors.New("read body failed: " + err.Error())
	}
	if len(body) > maxSkillDownloadBytes {
		return nil, "", errors.New("skill source too large (limit 10MB)")
	}
	return body, contentType, nil
}

// installFromZip 解压 zip 并安装其中的 skill
func installFromZip(data []byte) (*InstallSkillResult, error) {
	tmpRoot := filepath.Join(TempDir, "ai", "skill-install", gulu.Rand.String(7))
	if err := os.MkdirAll(tmpRoot, 0755); err != nil {
		return nil, err
	}
	defer os.RemoveAll(tmpRoot)

	zipPath := filepath.Join(tmpRoot, "src.zip")
	if err := os.WriteFile(zipPath, data, 0644); err != nil {
		return nil, err
	}
	unzipDir := filepath.Join(tmpRoot, "unzip")
	if err := os.MkdirAll(unzipDir, 0755); err != nil {

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Install a subdirectory skill via the tree/<branch>/<path> URL to reduce payload size.
  2. Use a raw SKILL.md link instead of the full-repo zip.
  3. Trim large assets out of the skill repository, or host a pre-built minimal zip.
  4. If the limit must rise, raise maxSkillDownloadBytes and rebuild the kernel (requires code change).

Example fix

// before — downloads the entire large repo as zip
util.InstallSkill("owner/big-repo")

// after — install only the skill subdirectory
util.InstallSkill("https://github.com/owner/big-repo/tree/main/skills/my-skill")
Defensive patterns

Strategy: validation

Validate before calling

// steer users to narrower sources for large repos
if strings.HasSuffix(src, ".git") || looksLikeFullRepo(src {
    // suggest the tree/<branch>/<path> form or a raw SKILL.md URL
}

Prevention

When it happens

Trigger: A zip archive or SKILL.md larger than 10 MiB; a URL that returns an unexpectedly large file (e.g. a full repository dump, a binary asset, or an HTML page with embedded data).

Common situations: Targeting a repo that bundles large assets (images, model files); accidentally pointing at a release containing big binaries; a monorepo whose zip is huge.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/4e9b5e1617762bd5. Report an issue: GitHub.