{"record":{"id":"ae90ebfca05c26ff","repo":"larksuite/cli","slug":"cannot-locate-binary-w","errorCode":null,"errorMessage":"cannot locate binary: %w","messagePattern":"cannot locate binary: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/selfupdate/updater.go","lineNumber":442,"sourceCode":"}\n\n// VerifyBinary checks that the installed binary reports the expected version\n// by running \"lark-cli --version\" and comparing the version token exactly.\n// Output format is \"lark-cli version X.Y.Z\"; the last field is extracted and\n// compared against expectedVersion (both stripped of any \"v\" prefix).\nfunc (u *Updater) VerifyBinary(expectedVersion string) error {\n\tif u.VerifyOverride != nil {\n\t\treturn u.VerifyOverride(expectedVersion)\n\t}\n\t// Prefer PATH resolution so npm global bin symlinks pick up the newly\n\t// installed binary (#836). If `lark-cli` is not on PATH (e.g. the user\n\t// invoked this process by absolute path), fall back to the running\n\t// executable — same as the pre-#836 secondary resolution path.\n\texe, err := execLookPath(\"lark-cli\")\n\tif err != nil {\n\t\texe, err = vfs.Executable()\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"cannot locate binary: %w\", err)\n\t\t}\n\t}\n\tctx, cancel := context.WithTimeout(context.Background(), verifyTimeout)\n\tdefer cancel()\n\tout, err := exec.CommandContext(ctx, exe, \"--version\").Output()\n\tif ctx.Err() == context.DeadlineExceeded {\n\t\treturn fmt.Errorf(\"binary verification timed out after %s\", verifyTimeout)\n\t}\n\tif err != nil {\n\t\treturn fmt.Errorf(\"binary not executable: %w\", err)\n\t}\n\tfields := strings.Fields(strings.TrimSpace(string(out)))\n\tif len(fields) == 0 {\n\t\treturn fmt.Errorf(\"empty version output\")\n\t}\n\tactual := strings.TrimPrefix(fields[len(fields)-1], \"v\")\n\texpected := strings.TrimPrefix(expectedVersion, \"v\")\n\tif actual != expected {","sourceCodeStart":424,"sourceCodeEnd":460,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/selfupdate/updater.go#L424-L460","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before\nexport PATH=/usr/local/bin:$PATH   # lark-cli installed to ~/.local/share/pnpm\n// after\nexport PATH=$HOME/.local/share/pnpm:/usr/local/bin:$PATH\nlark-cli --version   # now resolvable","handlingStrategy":"fallback","validationCode":"if _, err := exec.LookPath(\"lark-cli\"); err != nil { /* add the install bin dir to PATH before verifying */ }","typeGuard":"func binaryResolvable() bool { _, err := exec.LookPath(\"lark-cli\"); return err == nil }","tryCatchPattern":"if err := updater.VerifyBinary(expectedVersion); err != nil {\n\tif strings.Contains(err.Error(), \"cannot locate binary\") {\n\t\t// fall back to manual `lark-cli --version` after fixing PATH\n\t} else {\n\t\treturn err\n\t}\n}","preventionTips":["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"],"tags":["path","selfupdate","verification","binary"],"backgroundTag":"executable-not-found-in-path","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}