{"record":{"id":"9860effc170a3a0e","repo":"siyuan-note/siyuan","slug":"create-import-dir-failed-s","errorCode":null,"errorMessage":"create import dir failed: %s","messagePattern":"create import dir failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/util/httprequest.go","lineNumber":116,"sourceCode":"\tmaxReadBytes := int64(maxHTTPRequestBytes)\n\tif !isTextContentType(contentType) {\n\t\tmaxReadBytes = maxHTTPRequestFileBytes\n\t}\n\t// ContentLength 为 -1（chunked）时跳过大小预检，交由 LimitReader 兜底截断。\n\tif resp.ContentLength > maxReadBytes {\n\t\treturn statusCode, contentType, \"\", errors.New(\"response too large\")\n\t}\n\n\trespBody, rerr := io.ReadAll(io.LimitReader(resp.Body, maxReadBytes))\n\tif rerr != nil {\n\t\treturn statusCode, contentType, \"\", errors.New(\"read body failed: \" + rerr.Error())\n\t}\n\n\t// 二进制响应落盘，返回文件路径，供智能体按需进一步处理。\n\tif !isTextContentType(contentType) {\n\t\timportDir := filepath.Join(TempDir, \"import\")\n\t\tif merr := os.MkdirAll(importDir, 0755); merr != nil {\n\t\t\treturn statusCode, contentType, \"\", 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, respBody, 0644); werr != nil {\n\t\t\treturn statusCode, contentType, \"\", errors.New(\"write file failed: \" + werr.Error())\n\t\t}\n\t\treturn statusCode, contentType, fmt.Sprintf(\"Saved to: %s (%d bytes)\", filePath, len(respBody)), nil\n\t}\n\n\treturn statusCode, contentType, truncateRunes(string(respBody), maxHTTPRequestChars), nil\n}\n\n// sendByMethod 按 method 分发请求，统一走 NewBrowserRequest 返回的 *req.Request。\nfunc sendByMethod(request *req.Request, method, rawURL string) (*req.Response, error) {\n\tswitch method {\n\tcase \"GET\", \"\":\n\t\treturn request.Get(rawURL)\n\tcase \"POST\":","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/util/httprequest.go#L98-L134","documentation":"Raised by HTTPRequest when a non-text (binary) HTTP response cannot be saved to disk. After reading the response body, the function calls os.MkdirAll on TempDir/import to stage the downloaded file for the agent; if that mkdir fails the whole request aborts. The wrapped %s is the underlying OS error. This path is only hit for content types that isTextContentType rejects (anything other than text/*, application/json, application/xml, and the +json/+xml suffixes).","triggerScenarios":"util.HTTPRequest returns a binary Content-Type (e.g. image/png, application/pdf, application/octet-stream), then os.MkdirAll(filepath.Join(TempDir, \"import\"), 0755) fails. Typical causes: TempDir resolves to a path the process cannot create (read-only mount, removed parent), the disk is full, or a file (not a directory) already exists at that path.","commonSituations":"Running the kernel with TempDir pointing at a read-only or noexec filesystem; running as a user without write permission to the temp workspace; disk-full conditions during an agent http_request tool call that fetches a binary asset; a stale file named 'import' left in TempDir from a prior crash.","solutions":["Verify util.TempDir is set to a writable directory and that no regular file occupies TempDir/import (remove it if so).","Free disk space on the volume holding TempDir and retry the http_request call.","Run the kernel process with a user account that has create/write permission on the workspace temp directory.","If the asset is actually text but mis-served as binary, set a correct Accept header so isTextContentType returns true and the file-save branch is skipped."],"exampleFix":"// before: TempDir unwritable, binary save fails\n// after: point TempDir at a writable location before booting\nos.Setenv(\"TMPDIR\", \"/var/siyuan/tmp\")\n// or ensure the import dir is a directory, not a stray file\nimportDir := filepath.Join(util.TempDir, \"import\")\nif info, err := os.Stat(importDir); err == nil && !info.IsDir() {\n    os.Remove(importDir)\n}","handlingStrategy":"validation","validationCode":"// Pre-flight: ensure TempDir/import is creatable before issuing binary fetches.\nimportDir := filepath.Join(util.TempDir, \"import\")\nif info, err := os.Stat(importDir); err == nil && !info.IsDir() {\n    return fmt.Errorf(\"%s exists and is not a directory\", importDir)\n}\nif err := os.MkdirAll(importDir, 0755); err != nil {\n    return fmt.Errorf(\"import dir unavailable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep TempDir on a writable disk with adequate free space (>= maxHTTPRequestFileBytes = 10 MiB).","Never leave a regular file named 'import' in TempDir.","If you only need text, set Accept headers so isTextContentType returns true and skips the save branch."],"tags":["filesystem","http","mcp","agent-tool","disk-full"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}