multica-ai/multica · warning

successful runtime probes require all counts

Error message

successful runtime probes require all counts

What it means

The inverse rule from error 45: when probe_result is 'success', all four fields — runtime_count, provider_summary, online_count, offline_count — must be present (non-nil). A successful probe is expected to report its full count vector; the server will not default missing ones to zero because a silently missing count would be indistinguishable from an unreported probe. Pointer-nil checks mean explicit JSON nulls also fail here.

Source

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

		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")
		}
		providerTotal += int64(count)
	}
	if providerTotal != int64(*probe.RuntimeCount) {
		return validatedRuntimeProbe{}, errors.New("runtime provider counts do not match runtime_count")
	}
	summary, err := json.Marshal(probe.ProviderSummary)

View on GitHub (pinned to 2c0912b6ec)

Solutions

  1. On the success path always set all four fields; use {} for an empty provider_summary, 0 for zero counts.
  2. Remove omitempty from these four fields in the client payload struct, or branch to a success-specific struct.
  3. Never send JSON null for any of the four on success.
  4. Round-trip test: marshal a success probe and assert all four keys exist in the JSON.

Example fix

// before
type probePayload struct {
    Result        string           `json:"probe_result"`
    RuntimeCount  *int32           `json:"runtime_count,omitempty"`
    OnlineCount   *int32           `json:"online_count,omitempty"`
    OfflineCount  *int32           `json:"offline_count,omitempty"`
    Summary       map[string]int32 `json:"provider_summary,omitempty"`
}

// after
type probePayload struct {
    Result        string           `json:"probe_result"`
    RuntimeCount  *int32           `json:"runtime_count"`
    OnlineCount   *int32           `json:"online_count"`
    OfflineCount  *int32           `json:"offline_count"`
    Summary       map[string]int32 `json:"provider_summary"`
}
Defensive patterns

Strategy: type-guard

Validate before calling

const hasAllCounts = (p) =>
  Number.isInteger(p.runtime_count) && Number.isInteger(p.online_count) &&
  Number.isInteger(p.offline_count) && p.provider_summary !== null && p.provider_summary !== undefined;

function assertSuccessProbe(p) {
  if (normalizeProbeResult(p.probe_result) !== 'success') return;
  if (!hasAllCounts(p)) throw new TypeError('success probes require runtime_count, online_count, offline_count, and provider_summary ({} for empty)');
}

Type guard

const isSuccessProbeComplete = (p) => p.probe_result?.toLowerCase() === 'success' && ['runtime_count','online_count','offline_count'].every(k => Number.isInteger(p[k])) && typeof p.provider_summary === 'object' && p.provider_summary !== null;

Prevention

When it happens

Trigger: POST a success probe missing any key, e.g. {"probe_result":"success","runtime_count":10,"online_count":4,"offline_count":6} with no provider_summary, or with "online_count":null. All four must appear with concrete values.

Common situations: Client omitting provider_summary when the provider map is empty instead of sending {}; omitempty tags dropping zero-valued counts; partial refactor where a renamed field stopped serializing; nulls emitted for uncollected metrics.

Related errors


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