{"record":{"id":"42e1f9b2a75edd5d","repo":"siyuan-note/siyuan","slug":"write-file-failed-s-42e1f9","errorCode":null,"errorMessage":"write file failed: %s","messagePattern":"write file failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/util/webfetch.go","lineNumber":86,"sourceCode":"\t}\n\tif resp.ContentLength > maxReadBytes {\n\t\treturn \"\", errors.New(\"response too large\")\n\t}\n\n\tbody, err := io.ReadAll(io.LimitReader(resp.Body, maxReadBytes))\n\tif err != nil {\n\t\treturn \"\", errors.New(\"read body failed: \" + err.Error())\n\t}\n\n\tif !strings.HasPrefix(contentType, \"text/html\") && !strings.HasPrefix(contentType, \"text/plain\") {\n\t\timportDir := filepath.Join(TempDir, \"import\")\n\t\tif merr := os.MkdirAll(importDir, 0755); merr != nil {\n\t\t\treturn \"\", errors.New(\"create import dir failed: \" + merr.Error())\n\t\t}\n\t\tfilename := extractFilename(rawURL, contentType)\n\t\tfilePath := filepath.Join(importDir, filename)\n\t\tif werr := os.WriteFile(filePath, body, 0644); werr != nil {\n\t\t\treturn \"\", errors.New(\"write file failed: \" + werr.Error())\n\t\t}\n\t\treturn fmt.Sprintf(\"Saved to: %s (%d bytes)\", filePath, len(body)), nil\n\t}\n\n\thtmlStr := string(body)\n\n\tisHTML := strings.HasPrefix(contentType, \"text/html\")\n\tif !isHTML {\n\t\treturn truncateRunes(htmlStr, maxWebFetchChars), nil\n\t}\n\n\tif htmlStr == \"\" {\n\t\treturn \"\", nil\n\t}\n\n\tengine := NewLute()\n\tvar result string\n\tswitch format {","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/util/webfetch.go#L68-L104","documentation":"Returned at webfetch.go:86 when os.WriteFile(filePath, body, 0644) fails after the import directory was created successfully. The file payload was downloaded but could not be persisted. The %s is the OS write error.","triggerScenarios":"Disk full at the moment of writing, permission denied on the target path, a directory already exists at the target filename, path-too-long, antivirus locking the file (Windows), or a read-only filesystem mounted between mkdir and write.","commonSituations":"Disk filling up during a large download, filename extracted by extractFilename colliding with an existing directory, security software scanning/locking newly written files.","solutions":["Free disk space on the target volume.","Verify write permission and that no directory already uses the target filename.","Retry — transient AV locks often clear on the second attempt.","Check the filename produced by extractFilename for unexpected characters."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Best-effort free-space check on the import volume.\nfunc importVolumeHasSpace() error {\n    dir := filepath.Join(util.TempDir, \"import\")\n    if err := os.MkdirAll(dir, 0755); err != nil {\n        return err\n    }\n    var stat syscall.Statfs_t\n    if err := syscall.Statfs(dir, &stat); err != nil {\n        return err\n    }\n    if uint64(stat.Bavail)*uint64(stat.Bsize) < uint64(10*1024*1024) {\n        return errors.New(\"less than 10 MiB free\")\n    }\n    return nil\n}","typeGuard":"func isWriteFileFailed(err error) bool {\n    return err != nil && strings.HasPrefix(err.Error(), \"write file failed:\")\n}","tryCatchPattern":"out, err := util.WebFetch(raw, \"markdown\")\nif err != nil && isWriteFileFailed(err) {\n    // often transient (AV lock on Windows) — retry once\n    out, err = util.WebFetch(raw, \"markdown\")\n}","preventionTips":["Keep free disk space on the TempDir volume above the 10 MiB file cap.","On Windows, exclude the SiYuan temp/import dir from AV real-time scanning.","Avoid directory/file name collisions in the import dir."],"tags":["filesystem","permissions","io","disk-full"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}