larksuite/cli · error
expected version %s, got %q
Error message
expected version %s, got %q
What it means
VerifyBinary compares the actual version reported by the new binary (last whitespace-separated field, with a leading "v" trimmed) against the expected version it downloaded, and throws "expected version %s, got %q" on mismatch. This prevents installing a binary that is not the release the updater intended, e.g. a stale or mislabeled artifact.
Source
Thrown at internal/selfupdate/updater.go:461
}
}
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 {
if maxLen <= 0 {
return ""
}
r := []rune(s)
if len(r) <= maxLen {
return s
}
return string(r[len(r)-maxLen:])
}
// resolveExe returns the resolved path of the current running binary.
func (u *Updater) resolveExe() (string, error) {View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Compare the actual --version output with the release tag; re-download or re-publish the correct asset
- Purge CDN/proxy caches serving the old artifact
- Make the binary's last --version field exactly the version (optionally "v"-prefixed); fix the version stamping in the build
- Ensure the updater passes the same expectedVersion string form that the binary prints
Example fix
// before (binary prints build info last)
fmt.Printf("v%s (%s)\n", version, commit) // last field is commit -> mismatch
// after
fmt.Printf("v%s\n", version) // last field is the version Defensive patterns
Strategy: validation
Validate before calling
out, _ := exec.Command(binPath, "--version").Output()
fields := strings.Fields(strings.TrimSpace(string(out)))
if len(fields) == 0 { return fmt.Errorf("no version output") }
actual := strings.TrimPrefix(fields[len(fields)-1], "v")
expected := strings.TrimPrefix(expectedVersion, "v")
if actual != expected { return fmt.Errorf("stale artifact: want %s got %s", expected, actual) } Try / catch
if err := update.VerifyBinary(ctx, path, expectedVersion); err != nil {
var mismatch = err.Error()
if strings.HasPrefix(mismatch, "expected version") {
// purge cache and retry download once with the pinned asset URL
return retryWithFreshDownload()
}
return err
} Prevention
- Print only the version token (optionally v-prefixed) as the last --version field
- Pin release asset URLs and bust CDN caches on re-publish
- Stamp version at build time via -ldflags and assert it in release CI
- Keep expectedVersion format consistent with the binary's output format
When it happens
Trigger: The binary runs and prints a version, but after TrimPrefix("v") the last field of --version output does not equal the expectedVersion string passed to VerifyBinary.
Common situations: Release tag updated but the asset still points at an old build; CDN/cache serving a stale artifact; version string format changed (e.g. "1.2.3 (abc123)" where the last field is a commit hash, not the version); expected version passed with inconsistent "v" prefix handling.
Related errors
- npm not found in PATH: %w
- npm install timed out after %s
- pnpm not found in PATH: %w
- pnpm install timed out after %s
- official skills index redirected to non-HTTPS URL: %s
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/0f68593cbf7fe2a8.
Report an issue: GitHub.