siyuan-note/siyuan · error

create import dir failed

Error message

create import dir failed: %s

What it means

Binary responses are saved to disk under <workspace temp>/import before being reported to the agent, and os.MkdirAll failed while creating that directory. The suffix carries the OS error - typically permission denied, no space left on device, or a read-only filesystem. TempDir is the kernel workspace temp directory, set during boot.

Solutions

  1. Free space or raise the quota on the volume holding the SiYuan workspace temp directory
  2. Fix ownership/permissions so the kernel process can create directories under the temp dir
  3. Ensure the kernel went through normal boot so TempDir is set; restart after fixing the filesystem
  4. Retry the download once the filesystem issue is resolved

Example fix

// before: binary download attempted with unwritable temp dir
util.HTTPRequest("GET", "https://cdn.example.com/logo.png", nil, "")

// after: verify the import dir is writable before triggering binary downloads
importDir := filepath.Join(util.TempDir, "import")
if probe, perr := os.CreateTemp(importDir, "probe-*"); perr != nil {
    return perr // fix disk/permissions first
} else {
    probe.Close()
    os.Remove(probe.Name())
}
Defensive patterns

Strategy: try-catch

Validate before calling

importDir := filepath.Join(util.TempDir, "import")
if perr := os.MkdirAll(importDir, 0755); perr != nil {
    return fmt.Errorf("temp import dir unavailable: %w", perr)
}

Try / catch

if err != nil && strings.Contains(err.Error(), "create import dir failed") {
    // filesystem problem (space/permissions): report to the user; retrying the download cannot fix it
}

Prevention

When it happens

Trigger: Downloading a binary (image, zip, etc.) via util.HTTPRequest while the workspace temp directory is on a full disk, has restrictive ownership/permissions, sits on a read-only mount, or TempDir was never initialized in an unusual embedded/mobile context.

Common situations: Docker containers with a small tmpfs or full volume; workspace moved or restored with wrong ownership; disk quota exceeded; sandboxed environments where the kernel workspace is read-only.

Related errors


AI-assisted analysis of siyuan-note/siyuan@afa823b6b4 (2026-08-18). Data as JSON: /api/errors/9860effc170a3a0e. Report an issue: GitHub.

Appendix: source

Thrown at kernel/util/httprequest.go:363

	maxReadBytes := int64(maxHTTPRequestBytes)
	if !isTextContentType(contentType) {
		maxReadBytes = maxHTTPRequestFileBytes
	}
	// ContentLength 为 -1(chunked)时跳过大小预检,交由 LimitReader 兜底截断。
	if resp.ContentLength > maxReadBytes {
		return statusCode, contentType, "", errors.New("response too large")
	}

	respBody, rerr := io.ReadAll(io.LimitReader(resp.Body, maxReadBytes))
	if rerr != nil {
		return statusCode, contentType, "", errors.New("read body failed: " + rerr.Error())
	}

	// 二进制响应落盘,返回文件路径,供智能体按需进一步处理。
	if !isTextContentType(contentType) {
		importDir := filepath.Join(TempDir, "import")
		if merr := os.MkdirAll(importDir, 0755); merr != nil {
			return statusCode, contentType, "", errors.New("create import dir failed: " + merr.Error())
		}
		filename := extractFilename(rawURL, contentType)
		filePath := filepath.Join(importDir, filename)
		if werr := os.WriteFile(filePath, respBody, 0644); werr != nil {
			return statusCode, contentType, "", errors.New("write file failed: " + werr.Error())
		}
		return statusCode, contentType, fmt.Sprintf("Saved to: %s (%d bytes)", filePath, len(respBody)), nil
	}

	return statusCode, contentType, truncateRunes(string(respBody), maxHTTPRequestChars), nil
}

// isTextContentType 判断 Content-Type 是否为可直接展示给智能体的文本类响应。
// 覆盖 text/*、application/json、application/xml、application/*+json 等。
func isTextContentType(contentType string) bool {
	ct := strings.ToLower(strings.TrimSpace(strings.SplitN(contentType, ";", 2)[0]))
	if ct == "" {
		return false

View on GitHub (pinned to afa823b6b4)