{"record":{"id":"5045faeefb6849a0","repo":"siyuan-note/siyuan","slug":"failed-to-make-directory-w","errorCode":null,"errorMessage":"failed to make directory: %w","messagePattern":"failed to make directory: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/plugin/api_storage.go","lineNumber":278,"sourceCode":"\t\t\t\t\t\terr = fmt.Errorf(\"panic during siyuan.storage.put: %v\", r)\n\t\t\t\t\t}\n\n\t\t\t\t\tp.worker.Run(func(rt *goja.Runtime) (_ any, _ error) {\n\t\t\t\t\t\tif lo.IsNil(err) {\n\t\t\t\t\t\t\tif resolveErr := resolve(result); resolveErr != nil {\n\t\t\t\t\t\t\t\tlogging.LogErrorf(\"[plugin:%s] siyuan.storage.put resolve: %v\", p.Name, resolveErr)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif rejectErr := reject(rt.NewGoError(err)); rejectErr != nil {\n\t\t\t\t\t\t\t\tlogging.LogErrorf(\"[plugin:%s] siyuan.storage.put reject: %v\", p.Name, rejectErr)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn\n\t\t\t\t\t}, nil)\n\t\t\t\t}()\n\n\t\t\t\tif mkdirErr := os.MkdirAll(filepath.Dir(abs), 0755); mkdirErr != nil {\n\t\t\t\t\terr = fmt.Errorf(\"failed to make directory: %w\", mkdirErr)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif writeErr := filelock.WriteFile(abs, []byte(content)); writeErr != nil {\n\t\t\t\t\terr = fmt.Errorf(\"failed to write file: %w\", writeErr)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}()\n\n\t\t\treturn\n\t\t}, func(rt *goja.Runtime, result any, err error) {\n\t\t\tif !lo.IsNil(err) {\n\t\t\t\tif rejectErr := reject(rt.NewGoError(err)); rejectErr != nil {\n\t\t\t\t\tlogging.LogErrorf(\"[plugin:%s] siyuan.storage.put reject: %v\", p.Name, rejectErr)\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t\tif runErr != nil {","sourceCodeStart":260,"sourceCodeEnd":296,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/plugin/api_storage.go#L260-L296","documentation":"Thrown when os.MkdirAll on the parent directory of the target file fails. Before writing the file, put ensures filepath.Dir(abs) exists with mode 0755; if MkdirAll returns an error it is wrapped (note %w, so the underlying error is unwrap-able). Typical causes: permission denied on an ancestor, a parent path component that is a file rather than a directory, read-only filesystem, or invalid path syntax on the OS.","triggerScenarios":"put('a/b/c/state.json', body) where 'a/b' exists as a plain file; storage dir on a read-only mount; permission bits on the storage root prevent the plugin's user from creating directories; path contains characters illegal on Windows.","commonSituations":"Plugin nests deeply and one ancestor was created as a file by an earlier bug; containerized deployment mounted the storage volume read-only; UID mismatch between kernel process and storage dir owner.","solutions":["Inspect the wrapped error (errors.Unwrap or err.cause) for the OS-level reason.","Verify the storage directory is writable by the kernel process and no ancestor is a file.","Remount the storage volume read-write if it was accidentally mounted read-only.","Avoid creating overly deep or OS-illegal path segments."],"exampleFix":"// before\nawait siyuan.storage.put('data/state.json', body); // 'data' is a file\n// after\n// rename or remove the conflicting 'data' file, then:\nawait siyuan.storage.put('data/state.json', body);","handlingStrategy":"try-catch","validationCode":"// Pre-flight: avoid nesting under a path that is a file.\n// Keep storage paths shallow and do not reuse a filename as a directory.","typeGuard":null,"tryCatchPattern":"try {\n  await siyuan.storage.put(path, body);\n} catch (e) {\n  if (/failed to make directory/.test(String(e))) {\n    console.error('mkdir failed for', path, e);\n    // simplify the path or fix the conflicting ancestor\n  }\n  throw e;\n}","preventionTips":["Never create a file and a directory at the same relative path.","Ensure the storage volume is writable and not mounted read-only.","Keep directory depth modest to avoid ancestor permission issues."],"tags":["plugin-api","storage","filesystem","permissions","io-error"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}