siyuan-note/siyuan · error
write file failed
Error message
write file failed: %s
What it means
os.WriteFile failed while saving a downloaded binary response to <workspace temp>/import/<filename>; the filename is derived by extractFilename from the URL and content type. The suffix carries the OS error - disk full, permission denied, or (on Windows) a locked existing file. Text responses never hit this path.
Solutions
- Free disk space on the temp volume and retry the download
- Clean stale files out of <workspace temp>/import
- Check permissions on the target file/directory and exclude the temp dir from AV real-time scanning on Windows
Example fix
// before: import dir filled by earlier downloads, disk full
util.HTTPRequest("GET", bigFileURL, nil, "")
// after: clean stale imports before large downloads
importDir := filepath.Join(util.TempDir, "import")
if entries, derr := os.ReadDir(importDir); derr == nil {
for _, e := range entries {
os.Remove(filepath.Join(importDir, e.Name()))
}
} Defensive patterns
Strategy: try-catch
Validate before calling
if probe, perr := os.CreateTemp(filepath.Join(util.TempDir, "import"), "probe-*"); perr != nil {
return perr // disk full or read-only: skip the binary download
} else {
probe.Close()
os.Remove(probe.Name())
} Try / catch
if err != nil && strings.Contains(err.Error(), "write file failed") {
cleanImportDir() // remove stale files, then retry the download once
} Prevention
- Periodically clean <workspace temp>/import of downloaded files
- Keep disk headroom above the 10 MiB binary cap before agent sessions
- On Windows, exclude the temp dir from antivirus real-time scanning
When it happens
Trigger: Disk fills exactly between the mkdir and the write; the import directory is read-only; an antivirus or indexer holds the target file open on Windows; a same-named file exists with restrictive permissions.
Common situations: Repeated large downloads filling the temp volume; leftover files from earlier runs with different ownership; AV interference on Windows.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- create import dir failed
- enable encrypted notebook failed: failed to persist key…
- failed to persist key backup
- write file failed
- write notebook crypto backup failed
AI-assisted analysis of siyuan-note/siyuan@afa823b6b4 (2026-08-18).
Data as JSON: /api/errors/a1a0ac43714cc6f7.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/util/httprequest.go:368
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
}
if strings.HasPrefix(ct, "text/") {
return true
}
switch ct {View on GitHub (pinned to afa823b6b4)