larksuite/cli · error

open lock file: %w

Error message

open lock file: %w

What it means

TryLock opens (creating if necessary, mode 0600) the lock file through vfs.OpenFile before locking; failure here is wrapped as "open lock file: %w" with the underlying cause. This is an environment failure, not lock contention — the file itself could not be created or opened.

Source

Thrown at internal/lockfile/lockfile.go:54

	}
	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()
		return err
	}
	l.file = f
	return nil
}

// Unlock keeps the file on disk to avoid inode-reuse races between unlock and competing open+flock.
func (l *LockFile) Unlock() error {
	if l.file == nil {
		return nil
	}
	err := unlockFile(l.file)
	closeErr := l.file.Close()
	l.file = nil
	if err != nil {

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Inspect the wrapped cause for the concrete OS error (ENOENT/EACCES/EMFILE...).
  2. Recreate the lock directory (re-run the ForSubscribe path or mkdir with 0700).
  3. Fix filesystem permissions or free file descriptors (raise ulimit, close leaks).
  4. Ensure the path from Path() is valid for the current host (FileIO/vfs scoping).

Example fix

// before
f, _ := os.OpenFile(path, os.O_CREATE|os.O_RDWR, 0600) // dir missing
// after
os.MkdirAll(filepath.Dir(path), 0o700)
f, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR, 0o600)
if err != nil { return fmt.Errorf("open lock file: %w", err) }
Defensive patterns

Strategy: try-catch

Validate before calling

if _, err := os.Stat(filepath.Dir(lf.Path())); err != nil {
    return fmt.Errorf("lock dir missing: %w", err)
}

Try / catch

if err := lf.TryLock(); err != nil {
    if !errors.Is(err, lockfile.ErrHeld) {
        return fmt.Errorf("lock file unavailable: %w", err) // env problem
    }
}

Prevention

When it happens

Trigger: vfs.OpenFile fails inside TryLock: the parent lock directory was deleted after ForSubscribe, permissions deny write, path invalid, disk full, or too many open files.

Common situations: Another tool wiped the locks directory between ForSubscribe and TryLock; read-only filesystem; ulimit -n exhausted in long-running agents; config dir remounted read-only.

Related errors


AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04). Data as JSON: /api/errors/204e6fc2cc06921a. Report an issue: GitHub.