larksuite/cli · error
%s: cannot stat resolved path %q: %w
Error message
%s: cannot stat resolved path %q: %w
What it means
After successfully resolving a symlink with EvalSymlinks, resolveSymlinkIfAllowed re-stats the resolved path with vfs.Lstat to verify it exists and is not itself another symlink. If that Lstat fails (typically because the resolution raced with a deletion, or resolution crossed a permission boundary inconsistently), this wrapped error is returned instead of continuing the audit.
Source
Thrown at internal/binding/audit.go:110
// resolveSymlinkIfAllowed resolves a symlink to its target when
// params.AllowSymlinkPath is true, or rejects it otherwise. When the input
// is not a symlink, target is returned unchanged. A symlink that points to
// another symlink is rejected so callers only deal with a single hop.
func resolveSymlinkIfAllowed(target string, linfo fs.FileInfo, params AuditParams) (string, error) {
if linfo.Mode()&os.ModeSymlink == 0 {
return target, nil
}
if !params.AllowSymlinkPath {
return "", fmt.Errorf("%s: path %q is a symlink (not allowed)", params.Label, target)
}
resolved, err := vfs.EvalSymlinks(target)
if err != nil {
return "", fmt.Errorf("%s: cannot resolve symlink %q: %w", params.Label, target, err)
}
rinfo, err := vfs.Lstat(resolved)
if err != nil {
return "", fmt.Errorf("%s: cannot stat resolved path %q: %w", params.Label, resolved, err)
}
if rinfo.Mode()&os.ModeSymlink != 0 {
return "", fmt.Errorf("%s: resolved path %q is still a symlink", params.Label, resolved)
}
return resolved, nil
}
// requireInTrustedDirs enforces that effectivePath lives under one of the
// caller-declared trusted directories, if any were declared. An empty
// trustedDirs list disables the check.
func requireInTrustedDirs(effectivePath string, trustedDirs []string, label string) error {
if len(trustedDirs) == 0 {
return nil
}
cleaned := filepath.Clean(effectivePath)
for _, dir := range trustedDirs {
cleanDir := filepath.Clean(dir)
if cleaned == cleanDir || strings.HasPrefix(cleaned, cleanDir+"/") {View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Re-run the command; transient races between EvalSymlinks and Lstat usually disappear on retry
- Check the wrapped cause: ENOENT means the symlink target vanished — restore the target file or fix the symlink
- Check permissions (ls -ld) on the resolved path's parent directory for the current user
- Avoid running audits concurrently with operations that add/remove the target file
Example fix
// before: audit races with uninstall deleting target lark secrets resolve & apt remove tool & // after: run sequentially apt remove tool && lark secrets resolve
Defensive patterns
Strategy: retry
Validate before calling
func statStable(p string, attempts int) error {
for i := 0; i < attempts; i++ {
if _, err := os.Lstat(p); err == nil { return nil }
time.Sleep(100 * time.Millisecond)
}
return fmt.Errorf("path %s not stable/stat-able", p)
} Try / catch
eff, err := binding.AssertSecurePath(params)
if err != nil {
var perr *fs.PathError
if errors.As(err, &perr) && errors.Is(perr.Err, syscall.ENOENT) {
// target vanished; recreate or retry once
}
return err
} Prevention
- Do not run audits concurrently with deploys or cleanup jobs that touch the target
- Keep symlink targets on stable local filesystems
- Re-check the target exists immediately before invoking the CLI
When it happens
Trigger: AllowSymlinkPath is true, EvalSymlinks succeeds, but vfs.Lstat(resolved) fails: the resolved file was deleted between the two calls, the final directory denies access, or an OS-level error occurs on the resolved path.
Common situations: TOCTOU race where a package manager or cleanup job removes the file while the CLI audits it; symlink target inside a directory whose permissions changed mid-run; stale symlink into a now-unmounted filesystem where EvalSymlinks and Lstat disagree.
Related errors
- %s: cannot resolve symlink %q: %w
- %s: resolved path %q is still a symlink
- %s: path %q is a symlink (not allowed)
- %s: cannot stat %q: %w
- failed to read proxy plugin config %q: %w
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/0034a68100f34685.
Report an issue: GitHub.