multica-ai/multica · warning

runtime probe_result must be success or error

Error message

runtime probe_result must be success or error

What it means

validateClientUsageRuntime rejects a runtime telemetry probe whose `probe_result` field, after lowercasing and trimming, is neither 'success' nor 'error'. The endpoint ingests a fixed two-state probe outcome, so anything else — 'ok', 'failed', 'SUCCESS ' with weird casing is fine but 'partial', empty string — cannot be classified and is rejected before any database write. This is the gate for all subsequent count validation.

Source

Thrown at server/internal/handler/client_usage.go:189

	}

	w.WriteHeader(http.StatusNoContent)
}

func normalizeClientUsageOS(value string) string {
	value = strings.ToLower(strings.TrimSpace(value))
	switch value {
	case "macos", "windows", "linux", "ios", "android", "chromeos":
		return value
	default:
		return "unknown"
	}
}

func validateClientUsageRuntime(probe clientUsageRuntimeProbe) (validatedRuntimeProbe, error) {
	result := strings.ToLower(strings.TrimSpace(probe.ProbeResult))
	if result != "success" && result != "error" {
		return validatedRuntimeProbe{}, errors.New("runtime probe_result must be success or error")
	}
	validated := validatedRuntimeProbe{Result: pgtype.Text{String: result, Valid: true}}
	if result == "error" {
		if probe.RuntimeCount != nil || probe.ProviderSummary != nil || probe.OnlineCount != nil || probe.OfflineCount != nil {
			return validatedRuntimeProbe{}, errors.New("failed runtime probes must not include counts")
		}
		return validated, nil
	}

	if probe.RuntimeCount == nil || probe.ProviderSummary == nil || probe.OnlineCount == nil || probe.OfflineCount == nil {
		return validatedRuntimeProbe{}, errors.New("successful runtime probes require all counts")
	}
	if *probe.RuntimeCount < 0 || *probe.RuntimeCount > 1000 || *probe.OnlineCount < 0 || *probe.OfflineCount < 0 || *probe.OnlineCount+*probe.OfflineCount != *probe.RuntimeCount {
		return validatedRuntimeProbe{}, errors.New("invalid runtime counts")
	}
	if len(probe.ProviderSummary) > 32 {
		return validatedRuntimeProbe{}, errors.New("too many runtime providers")
	}

View on GitHub (pinned to 2c0912b6ec)

Solutions

  1. Send exactly "success" or "error" (case-insensitive) in probe_result.
  2. Map any local richer outcome (timeout, partial) to 'error' client-side before reporting.
  3. Centralize the allowed values in a shared constant/enum used by both client and server.
  4. Add a client-side unit test asserting emitted probe_result ∈ {success, error}.

Example fix

// before
{"probe_result": probe.timedOut ? "timeout" : "success"}

// after
{"probe_result": probe.timedOut ? "error" : "success"}
Defensive patterns

Strategy: validation

Validate before calling

const PROBE_RESULTS = new Set(['success', 'error']);

function normalizeProbeResult(raw) {
  const v = String(raw ?? '').trim().toLowerCase();
  if (!PROBE_RESULTS.has(v)) {
    throw new TypeError(`probe_result must be 'success' or 'error', got ${JSON.stringify(raw)}`);
  }
  return v;
}

Type guard

const isProbeResult = (v) => v === 'success' || v === 'error';

Prevention

When it happens

Trigger: POST client usage with runtime probe JSON like {"probe_result":"ok"}, {"probe_result":"failed"}, {"probe_result":""}, or a typo like {"probe_result":"sucess"}. Casing and surrounding whitespace are normalized, so only genuinely other tokens fail.

Common situations: Daemon/client code drift where a newer build emits 'partial' or 'timeout' states the server predates; hand-testing the endpoint with intuition-based values ('success'/'failure' pair assumed); enum renamed on one side of the contract during a refactor.

Related errors


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