multica-ai/multica · error · ErrCLIVersionMissing

multica CLI version not reported by daemon

Error message

multica CLI version not reported by daemon

What it means

ErrCLIVersionMissing is returned by CheckMinCLIVersion when the daemon did not report any CLI/handoff version to compare against MinHandoffCLIVersion. It is distinct from ErrCLIVersionTooOld: this error means version detection failed entirely (empty/unparseable report), not that a valid version was below the minimum. Callers branch on the two sentinels to show 'version not reported' vs 'needs upgrade'. Note dev-build version strings matching `git describe` output are treated as OK so `make daemon` stays unblocked.

Source

Thrown at server/pkg/agent/version.go:88

	}
	if devDescribeRe.MatchString(d) {
		return true
	}
	parsed, err := parseSemver(d)
	if err != nil {
		return false
	}
	min, err := parseSemver(MinHandoffCLIVersion)
	if err != nil {
		return false
	}
	return !parsed.lessThan(min)
}

// Errors returned by CheckMinCLIVersion. Callers branch on these to surface
// "needs upgrade" vs "version not reported" with the right user message.
var (
	ErrCLIVersionMissing = errors.New("multica CLI version not reported by daemon")
	ErrCLIVersionTooOld  = errors.New("multica CLI version is below required minimum")
)

// devDescribeRe matches the `git describe --tags --always --dirty` output for
// a build past the latest tag, e.g. `v0.2.15-235-gdaf0e935` (optionally with a
// trailing `-dirty`). Daemons built from source (Makefile `make build` / `make
// daemon`) report this shape; tagged releases are bare semver. Treating dev-
// described daemons as OK keeps `make daemon` unblocked without weakening the
// gate for staging or production users running stale stable releases.
var devDescribeRe = regexp.MustCompile(`^v?\d+\.\d+\.\d+-\d+-g[0-9a-fA-F]+`)

// CheckMinCLIVersion returns nil when `detected` parses as ≥ minimum. Returns
// ErrCLIVersionMissing for empty or unparsable input, and ErrCLIVersionTooOld
// when parsable but below the minimum. The caller can check for these
// sentinel errors with errors.Is to drive the response shape.
//
// Dev-built daemons (git-describe shape) always pass — the version string
// itself is the shared signal, so the modal pre-check and this server gate

View on GitHub (pinned to 2c0912b6ec)

Solutions

  1. Upgrade the daemon to a release that reports the multica CLI version, then retry.
  2. Restart the daemon if it was upgraded in place but is still running the old binary.
  3. Verify with the daemon's status/version endpoint that a non-empty version is now reported before re-invoking the handoff.

Example fix

// before
if err := version.CheckMinCLIVersion(detected); err != nil {
    return fmt.Errorf("handoff blocked: %v", err) // opaque
}

// after
if err := version.CheckMinCLIVersion(detected); err != nil {
    if errors.Is(err, version.ErrCLIVersionMissing) {
        return fmt.Errorf("daemon did not report a CLI version; upgrade and restart the daemon")
    }
    if errors.Is(err, version.ErrCLIVersionTooOld) {
        return fmt.Errorf("daemon CLI too old for handoff; upgrade to >= %s", version.MinHandoffCLIVersion)
    }
    return err
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Before starting a handoff, confirm the daemon reports a version
detected := daemon.ReportedCLIVersion()
if detected == "" {
    return errors.New("daemon reports no CLI version; upgrade/restart the daemon before handoff")
}

Try / catch

if err := version.CheckMinCLIVersion(detected); err != nil {
    switch {
    case errors.Is(err, version.ErrCLIVersionMissing):
        // show 'version not reported' + upgrade-daemon guidance; not fixable client-side
    case errors.Is(err, version.ErrCLIVersionTooOld):
        // show minimum version and upgrade instructions
    }
}

Prevention

When it happens

Trigger: Calling CheckMinCLIVersion with a detected version string that is empty or not reported by the daemon — e.g. an old daemon built before version reporting was added, or a daemon whose version probe failed and yielded an empty string.

Common situations: Running a stale daemon from before the handoff-version feature; a partially upgraded deployment where the CLI is new but the daemon was not restarted/upgraded; a custom daemon build that strips version info.

Related errors


AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15). Data as JSON: /api/errors/35294a5a9ff66b52. Report an issue: GitHub.