larksuite/cli · error
cannot locate binary
Error message
cannot locate binary: %w
What it means
VerifyBinary locates the freshly installed `lark-cli` to run `lark-cli --version`. It first tries execLookPath("lark-cli") and, failing that, falls back to vfs.Executable() (the running process's own binary). This error is returned when both resolution paths fail, meaning the binary's version cannot be verified.
Solutions
- Add the npm/pnpm global bin directory to PATH so `lark-cli` resolves (`which lark-cli` to confirm)
- Complete the update manually: `npm install -g @larksuite/cli@latest` or `pnpm add -g @larksuite/cli@latest`, then run `lark-cli --version`
- If the current binary was moved/deleted, restart from a known-good copy and retry the update
- Check the environment (container permissions, /proc availability) if vfs.Executable fails unexpectedly
Example fix
// before export PATH=/usr/local/bin:$PATH # lark-cli installed to ~/.local/share/pnpm // after export PATH=$HOME/.local/share/pnpm:/usr/local/bin:$PATH lark-cli --version # now resolvable
Defensive patterns
Strategy: fallback
Validate before calling
if _, err := exec.LookPath("lark-cli"); err != nil { /* add the install bin dir to PATH before verifying */ } Type guard
func binaryResolvable() bool { _, err := exec.LookPath("lark-cli"); return err == nil } Try / catch
if err := updater.VerifyBinary(expectedVersion); err != nil {
if strings.Contains(err.Error(), "cannot locate binary") {
// fall back to manual `lark-cli --version` after fixing PATH
} else {
return err
}
} Prevention
- Keep the npm/pnpm global bin directory on PATH
- Do not delete or move the running binary during an update
- Verify `which lark-cli` after every update
- Avoid restricted containers that break /proc-based self-executable resolution
When it happens
Trigger: Calling Updater.VerifyBinary (e.g. from doAutoUpdate after an update) when `lark-cli` is not on PATH AND the running executable's path cannot be determined (vfs.Executable returns an error).
Common situations: Update installed the binary into a directory not on PATH (npm/pnpm global bin dir missing from PATH); the running binary was deleted/moved mid-update so Executable fails; restricted container environments where /proc self-exe resolution fails.
Related errors
- binary verification timed out after
- binary not executable
- npm not found in PATH
- pnpm not found in PATH
- cannot rename binary for update
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/ae90ebfca05c26ff.
Report an issue: GitHub.
Appendix: source
Thrown at internal/selfupdate/updater.go:442
}
// VerifyBinary checks that the installed binary reports the expected version
// by running "lark-cli --version" and comparing the version token exactly.
// Output format is "lark-cli version X.Y.Z"; the last field is extracted and
// compared against expectedVersion (both stripped of any "v" prefix).
func (u *Updater) VerifyBinary(expectedVersion string) error {
if u.VerifyOverride != nil {
return u.VerifyOverride(expectedVersion)
}
// Prefer PATH resolution so npm global bin symlinks pick up the newly
// installed binary (#836). If `lark-cli` is not on PATH (e.g. the user
// invoked this process by absolute path), fall back to the running
// executable — same as the pre-#836 secondary resolution path.
exe, err := execLookPath("lark-cli")
if err != nil {
exe, err = vfs.Executable()
if err != nil {
return fmt.Errorf("cannot locate binary: %w", err)
}
}
ctx, cancel := context.WithTimeout(context.Background(), verifyTimeout)
defer cancel()
out, err := exec.CommandContext(ctx, exe, "--version").Output()
if ctx.Err() == context.DeadlineExceeded {
return fmt.Errorf("binary verification timed out after %s", verifyTimeout)
}
if err != nil {
return fmt.Errorf("binary not executable: %w", err)
}
fields := strings.Fields(strings.TrimSpace(string(out)))
if len(fields) == 0 {
return fmt.Errorf("empty version output")
}
actual := strings.TrimPrefix(fields[len(fields)-1], "v")
expected := strings.TrimPrefix(expectedVersion, "v")
if actual != expected {View on GitHub (pinned to 7fd6ef3c07)