multica-ai/multica · warning

failed runtime probes must not include counts

Error message

failed runtime probes must not include counts

What it means

validateClientUsageRuntime enforces mutual exclusion: when probe_result is 'error', none of runtime_count, provider_summary, online_count, offline_count may be present (non-nil). A failed probe has nothing meaningful to count, so attaching counts is treated as a contract violation rather than ignored — this keeps the stored telemetry unambiguous. The check uses pointer nil-ness, so an explicit JSON null is acceptable; only present-with-value fields fail.

Source

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

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")
	}
	var providerTotal int64
	for provider, count := range probe.ProviderSummary {
		if !providerNamePattern.MatchString(provider) || count < 0 || count > 1000 {
			return validatedRuntimeProbe{}, errors.New("invalid runtime provider summary")
		}

View on GitHub (pinned to 2c0912b6ec)

Solutions

  1. On the error path, omit all four count/summary fields entirely (use omitempty / conditional serialization).
  2. Use explicit JSON nulls rather than {} or 0 if your serializer cannot skip fields.
  3. Build the request payload with a discriminated builder that branches on probe outcome.
  4. Add a contract test: error probes must serialize without any count keys.

Example fix

// before
type probePayload struct {
    Result          string           `json:"probe_result"`
    RuntimeCount    *int32           `json:"runtime_count"`
}
p := probePayload{Result: "error", RuntimeCount: &zero}

// after
type probePayload struct {
    Result          string           `json:"probe_result"`
    RuntimeCount    *int32           `json:"runtime_count,omitempty"`
}
p := probePayload{Result: "error"} // leave counts nil
Defensive patterns

Strategy: type-guard

Validate before calling

function buildProbePayload(probe) {
  const result = normalizeProbeResult(probe.result);
  if (result === 'error') {
    // must include NO count fields at all
    return { probe_result: result };
  }
  return {
    probe_result: result,
    runtime_count: probe.runtimeCount,
    online_count: probe.onlineCount,
    offline_count: probe.offlineCount,
    provider_summary: probe.providerSummary,
  };
}

Type guard

const isErrorProbe = (p) => normalizeProbeResult(p.result) === 'error';

const errorProbeIsClean = (p) => isErrorProbe(p) && p.runtime_count === undefined && p.provider_summary === undefined && p.online_count === undefined && p.offline_count === undefined;

Prevention

When it happens

Trigger: POST a probe with probe_result="error" plus any of {"runtime_count":0}, {"provider_summary":{}}, {"online_count":0}, {"offline_count":0}. Note {} for provider_summary counts as present and fails; explicit "provider_summary":null does not.

Common situations: Client reusing one struct for both outcomes and zero-filling fields instead of omitting them; JSON serializer configured to emit zeros rather than omitempty; a 'best effort' client that includes whatever counts it happened to collect before the failure.

Related errors


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