larksuite/cli · error
create lock dir: %w
Error message
create lock dir: %w
What it means
ForSubscribe creates <config-dir>/locks with mode 0700 via vfs.MkdirAll before writing the lock file; if that fails it wraps the underlying error. This guards all subsequent lock-file creation against a missing or uncreatable config directory.
Source
Thrown at internal/lockfile/lockfile.go:39
var ErrHeld = errors.New("lockfile: lock already held")
type LockFile struct {
path string
file *os.File
}
func New(path string) *LockFile {
return &LockFile{path: path}
}
// ForSubscribe sanitises appID against path traversal before forming the lock filename.
func ForSubscribe(appID string) (*LockFile, error) {
if appID == "" {
return nil, fmt.Errorf("app ID must not be empty")
}
dir := filepath.Join(core.GetConfigDir(), "locks")
if err := vfs.MkdirAll(dir, 0700); err != nil {
return nil, fmt.Errorf("create lock dir: %w", err)
}
safe := safeIDChars.ReplaceAllString(appID, "_")
name := filepath.Base(fmt.Sprintf("subscribe_%s.lock", safe))
path := filepath.Join(dir, name)
return New(path), nil
}
// TryLock acquires an exclusive non-blocking lock; auto-released on process exit.
func (l *LockFile) TryLock() error {
if l.file != nil {
return fmt.Errorf("%w: %s", ErrHeld, l.path)
}
f, err := vfs.OpenFile(l.path, os.O_CREATE|os.O_RDWR, 0600)
if err != nil {
return fmt.Errorf("open lock file: %w", err)
}
if err := tryLockFile(f); err != nil {
f.Close()View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Check the error wrapped in %w for the concrete cause (permission vs disk vs path).
- Point LARKSUITE_CLI_CONFIG_DIR to a writable directory.
- Fix permissions on the config dir / home directory (mkdir/chmod as needed).
- Free disk space or raise quota if the failure is ENOSPC.
Example fix
// before export LARKSUITE_CLI_CONFIG_DIR=/root/.config # read-only container // after export LARKSUITE_CLI_CONFIG_DIR=/tmp/lark-config # writable path # or: chmod u+rwX ~/.config
Defensive patterns
Strategy: validation
Validate before calling
cfgDir := os.Getenv("LARKSUITE_CLI_CONFIG_DIR")
if cfgDir == "" { cfgDir = filepath.Join(os.Getenv("HOME"), ".config") }
if info, err := os.Stat(cfgDir); err != nil || !info.IsDir() {
return fmt.Errorf("config dir %q unavailable", cfgDir)
} Prevention
- Point LARKSUITE_CLI_CONFIG_DIR at a writable path in containers/CI
- Check disk space and permissions on the config directory
- Pre-create and chmod 0700 the config dir in setup scripts
When it happens
Trigger: vfs.MkdirAll fails while calling lockfile.ForSubscribe — e.g. the config dir is read-only, does not exist and cannot be created, disk full, or permission denied on the user's home/config path.
Common situations: Running in a container with a read-only or non-writable HOME; LARKSUITE_CLI_CONFIG_DIR pointing to an invalid/unwritable path; disk quota exceeded; sandboxed CI runners restricting writes.
Related errors
- create config dir: %w
- %s: cannot stat %q: %w
- %s: path %q is world-readable (mode %04o)
- %s: path %q is group-readable (mode %04o)
- failed to read secret file %s: %w
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/66c8997595a4544b.
Report an issue: GitHub.