fish2018/pansou · error
创建存储目录失败
Error message
创建存储目录失败: %v
What it means
QQPDPlugin.Initialize (plugin/qqpd/qqpd.go:534) fails when os.MkdirAll on the '<cachePath>/qqpd_users' directory (default ./cache) returns an error, typically a filesystem permission problem or an unwritable path. Initialization aborts, so the QQPD plugin does not start.
Solutions
- Check permissions on the cache directory parent (ls -ld ./cache) and grant write access to the process user
- Set the cache path configuration to a writable location (e.g. /var/lib/<app>/cache)
- If running in Docker, mount a writable volume at the cache path
- Verify the path isn't an existing regular file that blocks directory creation
Example fix
// before cachePath = "./cache" // after (config) cachePath = "/var/lib/qqpd/cache" # plus: chown appuser /var/lib/qqpd
Defensive patterns
Strategy: validation
Validate before calling
const storageDir = filepath.Join(cachePath, "qqpd_users")
if fi, err := os.Stat(filepath.Dir(storageDir)); err != nil || !fi.IsDir() {
return fmt.Errorf("cache path %q not writable directory", filepath.Dir(storageDir))
}
if err := os.WriteFile(filepath.Join(filepath.Dir(storageDir), ".probe"), nil, 0644); err != nil {
return fmt.Errorf("cache path not writable: %w", err)
} Try / catch
if err := p.Initialize(); err != nil {
if strings.Contains(err.Error(), "创建存储目录失败") {
os.Exit(1) // or fall back to a writable temp dir
}
return err
} Prevention
- Run the process as a user with write access to the working directory
- Mount a writable volume for the cache path in containers
- Pre-create the cache directory with correct ownership in deployment scripts
- Avoid read-only root filesystems without an explicit writable data mount
When it happens
Trigger: os.MkdirAll(StorageDir, 0755) fails during Initialize — e.g. cachePath resolves to a read-only mount, the process user lacks write permission on the parent directory, a file already exists at the target path, or the disk is full.
Common situations: Running the bot as a non-root user whose working directory is not writable, deploying in a read-only Docker container filesystem, or configuring a cachePath pointing to an invalid/mounted read-only volume.
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/8ead80ed80db607e.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/qqpd/qqpd.go:534
plugin.RegisterGlobalPlugin(p)
}
// Initialize 实现 InitializablePlugin 接口,延迟初始化插件
func (p *QQPDPlugin) Initialize() error {
if p.initialized {
return nil
}
// 初始化存储目录路径
cachePath := os.Getenv("CACHE_PATH")
if cachePath == "" {
cachePath = "./cache"
}
StorageDir = filepath.Join(cachePath, "qqpd_users")
// 初始化存储目录
if err := os.MkdirAll(StorageDir, 0755); err != nil {
return fmt.Errorf("创建存储目录失败: %v", err)
}
// 加载所有用户到内存
p.loadAllUsers()
// 启动定期清理任务
go p.startCleanupTask()
p.initialized = true
return nil
}
// ============ 插件接口实现 ============
// SkipServiceFilter 返回是否跳过Service层的关键词过滤
// 注释掉:让Service层来处理过滤,Service层会根据每个链接的标题进行精确过滤
// func (p *QQPDPlugin) SkipServiceFilter() bool {
// return trueView on GitHub (pinned to beaa561337)