larksuite/cli · error

failed to stat proxy plugin config %q: %w

Error message

failed to stat proxy plugin config %q: %w

What it means

This error comes from transport.Load (internal/transport/config.go) when vfs.Stat on the proxy plugin config file (~/.lark-cli/proxy_config.json) fails with an error other than 'not exists'. Load is a one-shot cached loader that decides how all outbound CLI traffic is routed (proxy address and trusted CA), so it must be able to stat this file before auditing its safety. The wrapped err preserves the OS-level cause (e.g. permission denied, ELOOP).

Source

Thrown at internal/transport/config.go:90

		cfg, hasEnv, err := loadFromEnv()
		if err != nil {
			loadErr = err
			return
		}

		p := Path()
		if _, err := vfs.Stat(p); err != nil {
			if errors.Is(err, os.ErrNotExist) {
				// No file: return env-only config (if any), else nil.
				if hasEnv {
					loadCfg = cfg
				} else {
					loadCfg = nil
				}
				loadErr = nil
				return
			}
			loadErr = fmt.Errorf("failed to stat proxy plugin config %q: %w", p, err)
			return
		}
		// Security hardening: this config dictates where ALL outbound CLI traffic
		// egresses and which extra CA is trusted, so a file another local user or
		// process can tamper with (symlink, foreign owner, group/world-writable)
		// could redirect credential traffic. Audit it the same way the CA file is.
		safePath, err := binding.AssertSecurePath(binding.AuditParams{
			TargetPath:            p,
			Label:                 ConfigFileName,
			AllowReadableByOthers: true, // config is not a secret; only writability/owner/symlink matter
		})
		if err != nil {
			loadErr = fmt.Errorf("unsafe proxy plugin config %q: %w", p, err)
			return
		}
		b, err := vfs.ReadFile(safePath)
		if err != nil {
			loadErr = fmt.Errorf("failed to read proxy plugin config %q: %w", p, err)

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Inspect the wrapped OS error to identify the exact cause (permission, loop, I/O)
  2. Fix permissions: chmod/chown ~/.lark-cli and proxy_config.json so your running user can stat it
  3. Check for symlink loops: ls -la the file and run file on it; replace a broken symlink with a real file or correct target
  4. As a last resort, delete the unusable config file (Load treats a missing file as env-only config) and rely on proxy env vars

Example fix

// before
ls -la ~/.lark-cli/proxy_config.json -> Permission denied

// after
chmod u+rx ~/.lark-cli && chmod u+r ~/.lark-cli/proxy_config.json
Defensive patterns

Strategy: validation

Validate before calling

p := filepath.Join(core.GetConfigDir(), transport.ConfigFileName)
if _, err := os.Stat(p); err != nil && !errors.Is(err, os.ErrNotExist) {
    return fmt.Errorf("proxy config unusable, fix before running CLI: %w", err)
}

Try / catch

cfg, err := transport.Load()
if err != nil {
    var pe *fs.PathError
    if errors.As(err, &pe) && pe.Op == "stat" {
        log.Printf("cannot stat %s: %v — fix perms/symlinks or delete the file", pe.Path, pe.Err)
    }
}

Prevention

When it happens

Trigger: The config file path exists per directory listing but Stat fails: permission denied on the file or an ancestor directory, too many symlinks (ELOOP), an I/O error, or a path whose parent is not readable/searchable. It is NOT raised when the file simply does not exist (that returns env-only config).

Common situations: A user or process hardened ~/.lark-cli with overly restrictive permissions so another account cannot even stat the file; running the CLI under a different user/service account than the one that created the config; a symlink loop left by a misconfigured dotfile manager (stow/chezmoi); filesystem errors on a network-mounted home directory.

Related errors


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