{"record":{"id":"08a3a7a73a15e6e4","repo":"fish2018/pansou","slug":"v-08a3a7","errorCode":null,"errorMessage":"创建存储目录失败: %v","messagePattern":"创建存储目录失败: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/gying/gying.go","lineNumber":783,"sourceCode":"\treturn baseURL, nil\n}\n\n// Initialize 实现 InitializablePlugin 接口，延迟初始化插件\nfunc (p *GyingPlugin) Initialize() error {\n\tif p.initialized {\n\t\treturn nil\n\t}\n\n\t// 初始化存储目录路径\n\tcachePath := os.Getenv(\"CACHE_PATH\")\n\tif cachePath == \"\" {\n\t\tcachePath = \"./cache\"\n\t}\n\tStorageDir = filepath.Join(cachePath, \"gying_users\")\n\n\t// 初始化存储目录\n\tif err := os.MkdirAll(StorageDir, 0755); err != nil {\n\t\treturn fmt.Errorf(\"创建存储目录失败: %v\", err)\n\t}\n\n\t// 加载站点配置\n\tif err := p.loadConfig(); err != nil {\n\t\treturn fmt.Errorf(\"加载站点配置失败: %v\", err)\n\t}\n\n\t// 加载所有用户到内存\n\tp.loadAllUsers()\n\n\t// 异步初始化默认账户（不阻塞启动）\n\tgo func() {\n\t\t// 延迟1秒，等待主程序完全启动\n\t\ttime.Sleep(1 * time.Second)\n\t\tp.initDefaultAccounts()\n\t}()\n\n\t// 启动定期清理任务","sourceCodeStart":765,"sourceCodeEnd":801,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/gying/gying.go#L765-L801","documentation":"Raised at plugin/gying.go:783 during plugin initialization. The plugin determines StorageDir = <cachePath>/gying_users and calls os.MkdirAll(StorageDir, 0755); if directory creation fails (permission denied, path is a file, unwritable parent), the OS error is wrapped with this message and initialization aborts.","triggerScenarios":"Plugin Init with cachePath unset (defaults to ./cache) or set to an unwritable/nonexistent location; MkdirAll fails because a parent component is a file, or the process lacks write permission on the parent.","commonSituations":"Running the app in a read-only container or working directory; deploying as a non-root user while cachePath points to a root-owned path; ./cache accidentally replaced by a regular file.","solutions":["Read the wrapped %v error to confirm the cause (permission denied vs not-a-directory).","Ensure the cache directory's parent exists and is writable: mkdir -p ./cache && chmod 755 ./cache.","If ./cache is a regular file, remove or rename it so it can be a directory.","Configure cachePath to a writable location and rerun.","In containers, mount a writable volume at the cache path."],"exampleFix":"// before\nos.Setenv/... cachePath = \"/ro-mount/cache\" // read-only mount\n// after\ncachePath = \"/var/cache/app\" // writable location; mkdir -p /var/cache/app","handlingStrategy":"validation","validationCode":"dir := filepath.Join(cachePath, \"gying_users\")\nif info, err := os.Stat(filepath.Dir(dir)); err != nil || !info.IsDir() { return fmt.Errorf(\"cache parent missing: %s\", filepath.Dir(dir)) }\nif f, err := os.CreateTemp(filepath.Dir(dir), \".w*\"); err != nil { return fmt.Errorf(\"cache path not writable\") } else { f.Close(); os.Remove(f.Name()) }","typeGuard":null,"tryCatchPattern":"if err := plugin.Init(); err != nil {\n\tvar pe *fs.PathError\n\tif errors.As(err, &pe) && errors.Is(pe.Err, syscall.EACCES) {\n\t\tlog.Printf(\"cannot create storage dir (permissions): %v\", err)\n\t}\n\treturn err\n}","preventionTips":["Ensure ./cache (or the configured cachePath) exists and is writable before starting the app.","Never place a regular file where the cache directory is expected.","In containers, mount a writable volume for the cache path and run as a user with write access."],"tags":["filesystem","mkdir","init","permissions"],"backgroundTag":"mkdir-permission-denied","analyzedSha":"beaa56133755a548ebc51b090b3816e2ae044aa6","analyzedAt":"2026-09-07T00:31:18.025Z","contentChangedAt":"2026-09-07T00:31:18.025Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}