larksuite/cli · error

empty version output

Error message

empty version output

What it means

After successfully running the new binary with `--version`, VerifyBinary tokenizes its stdout with strings.Fields and throws "empty version output" if there are no fields. This guards against installing a binary that runs but prints nothing on --version, which would make version verification meaningless.

Source

Thrown at internal/selfupdate/updater.go:456

	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 {
	if maxLen <= 0 {
		return ""
	}
	r := []rune(s)
	if len(r) <= maxLen {
		return s
	}

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Check what the downloaded binary actually prints with `./binary --version`; fix the release artifact if it prints nothing
  2. Ensure --version output goes to stdout (Output() only captures stdout)
  3. Re-publish a correct release and re-run the update
  4. Verify the download URL did not return an error page instead of the binary

Example fix

// before (Go binary prints version to stderr)
fmt.Fprintf(os.Stderr, "v%s\n", version) // empty stdout -> "empty version output"
// after
fmt.Printf("v%s\n", version) // stdout, e.g. "mycli v1.2.3"
Defensive patterns

Strategy: validation

Validate before calling

out, err := exec.Command(binPath, "--version").Output()
if err != nil { return err }
if len(strings.Fields(strings.TrimSpace(string(out)))) == 0 {
    return fmt.Errorf("binary %s prints no --version output", binPath)
}

Try / catch

if err := update.VerifyBinary(ctx, path, expectedVersion); err != nil {
    if strings.Contains(err.Error(), "empty version output") {
        log.Printf("artifact at %s is not a valid CLI build; skipping auto-update", path)
    }
    return err
}

Prevention

When it happens

Trigger: The executed binary exits with code 0 but writes no output (or only whitespace) to stdout, so strings.Fields on the trimmed output yields zero fields.

Common situations: The artifact is a stub or wrong file (e.g. an HTML error page saved as the binary that happens to run, a wrapper script echoing nothing); a repackaged binary whose --version prints to stderr instead of stdout; a build misconfiguration producing a no-op main().

Related errors


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