larksuite/cli · error

binary verification timed out after %s

Error message

binary verification timed out after %s

What it means

VerifyBinary runs `lark-cli --version` with a context bounded by verifyTimeout. If the child process does not exit before the deadline, the context cancels it and this error is returned to signal that binary verification timed out.

Source

Thrown at internal/selfupdate/updater.go:449

	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 {
		return fmt.Errorf("expected version %s, got %q", expectedVersion, actual)
	}
	return nil
}

// Truncate returns the last maxLen runes of s.
func Truncate(s string, maxLen int) string {

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Run `lark-cli --version` manually to see whether the binary hangs and diagnose its startup
  2. Reinstall the binary (`npm install -g @larksuite/cli@latest` or `pnpm add -g @larksuite/cli@latest`) if it is corrupted
  3. Check PATH for shims/wrappers (nvm, version managers) that may block startup and bypass them
  4. Retry the update on a healthier environment (faster disk, no stale locks)

Example fix

// diagnose instead of failing silently
res := doAutoUpdate()
if strings.Contains(fmt.Sprint(res), "binary verification timed out") {
	out, err := exec.Command("lark-cli", "--version").CombinedOutput() // run manually to see hang
	log.Printf("manual version check: out=%s err=%v", out, err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

// sanity: current binary should respond quickly
out, err := exec.Command("lark-cli", "--version").Output()
if err != nil { /* hanging/corrupt binary; reinstall before VerifyBinary */ }

Try / catch

if err := updater.VerifyBinary(expectedVersion); err != nil {
	if strings.Contains(err.Error(), "verification timed out") {
		// hung binary: reinstall manually and re-verify
	} else {
		return err
	}
}

Prevention

When it happens

Trigger: Calling Updater.VerifyBinary (from doAutoUpdate) when the spawned `lark-cli --version` process exceeds verifyTimeout, i.e. ctx.Err() == context.DeadlineExceeded after cmd.Output().

Common situations: A stale or corrupted installed binary that hangs on startup instead of printing a version; the shell wrapper/shim on PATH blocking on something (e.g. nvm init, a locked filesystem); extremely slow disk or a broken install where the new binary deadlocks.

Understand the failure class

Related errors


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