fish2018/pansou · error
创建存储目录失败
Error message
创建存储目录失败: %w
What it means
PanlianPlugin.Initialize creates the per-user storage directory <cachePath>/panlian_users via os.MkdirAll; if that fails (permissions, read-only FS, path occupied by a file) it returns '创建存储目录失败' wrapping the OS error. This aborts plugin initialization.
Solutions
- Check that the configured cache path (default ./cache) exists as a directory and is writable by the process user: ls -ld ./cache.
- Fix permissions (chown/chmod) or run from a working directory where a writable ./cache can be created.
- Point the plugin's cachePath config at a persistent writable directory (e.g. /var/lib/yourapp/cache).
- Remove any regular file occupying the panlian_users path.
Example fix
// before cachePath = "./cache" // read-only in container // after cachePath = "/var/lib/mediasearch/cache" // writable volume
Defensive patterns
Strategy: validation
Validate before calling
import "os"
func dirWritable(path string) bool {
if fi, err := os.Stat(path); err == nil && !fi.IsDir() {
return false
}
probe := filepath.Join(path, ".write_probe")
if err := os.WriteFile(probe, nil, 0o644); err != nil {
return false
}
os.Remove(probe)
return true
}
// call before Initialize: dirWritable("./cache") Try / catch
if err := plugin.Initialize(cachePath, cfg); err != nil {
if strings.Contains(err.Error(), "创建存储目录失败") {
log.Fatalf("cache dir unusable: %v — set cachePath to a writable dir", err)
}
return err
} Prevention
- Configure cachePath to a guaranteed-writable volume, not the process CWD.
- Check container/systemd read-only mounts (ProtectSystem, readOnlyRootFilesystem) before deploying.
- Ensure the cache dir is owned by the same user the service runs as.
- Pre-create the directory in deployment scripts with correct ownership.
When it happens
Trigger: os.MkdirAll(storageDir, 0o755) fails because cachePath is unwritable, its parent is a regular file, the disk is full, or the process lacks write permission on the cache path.
Common situations: Running in a read-only container or systemd unit with ProtectSystem=strict; ./cache pre-created by root then app run as another user; cachePath mistakenly set to a file path; disk quota exceeded.
Understand the failure class
Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/28cbc5db3d2c437d.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/panlian/panlian.go:532
}
func (p *PanlianPlugin) Description() string {
return Description
}
func (p *PanlianPlugin) Initialize() error {
if p.initialized {
return nil
}
cachePath := os.Getenv("CACHE_PATH")
if cachePath == "" {
cachePath = "./cache"
}
storageDir = filepath.Join(cachePath, "panlian_users")
if err := os.MkdirAll(storageDir, 0o755); err != nil {
return fmt.Errorf("创建存储目录失败: %w", err)
}
if err := p.loadConfig(); err != nil {
return fmt.Errorf("加载配置失败: %w", err)
}
p.loadAllUsers()
p.initialized = true
return nil
}
func (p *PanlianPlugin) RegisterWebRoutes(router *gin.RouterGroup) {
group := router.Group("/panlian")
group.GET("/:param", p.handleManagePage)
group.POST("/:param", p.handleManagePagePOST)
}
func (p *PanlianPlugin) Search(keyword string, ext map[string]interface{}) ([]model.SearchResult, error) {
result, err := p.SearchWithResult(keyword, ext)
if err != nil {View on GitHub (pinned to beaa561337)