{"record":{"id":"0bb3d718df7fa35c","repo":"multica-ai/multica","slug":"runtime-probe-result-must-be-success-or-error","errorCode":null,"errorMessage":"runtime probe_result must be success or error","messagePattern":"runtime probe_result must be success or error","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"warning","filePath":"server/internal/handler/client_usage.go","lineNumber":189,"sourceCode":"\t}\n\n\tw.WriteHeader(http.StatusNoContent)\n}\n\nfunc normalizeClientUsageOS(value string) string {\n\tvalue = strings.ToLower(strings.TrimSpace(value))\n\tswitch value {\n\tcase \"macos\", \"windows\", \"linux\", \"ios\", \"android\", \"chromeos\":\n\t\treturn value\n\tdefault:\n\t\treturn \"unknown\"\n\t}\n}\n\nfunc validateClientUsageRuntime(probe clientUsageRuntimeProbe) (validatedRuntimeProbe, error) {\n\tresult := strings.ToLower(strings.TrimSpace(probe.ProbeResult))\n\tif result != \"success\" && result != \"error\" {\n\t\treturn validatedRuntimeProbe{}, errors.New(\"runtime probe_result must be success or error\")\n\t}\n\tvalidated := validatedRuntimeProbe{Result: pgtype.Text{String: result, Valid: true}}\n\tif result == \"error\" {\n\t\tif probe.RuntimeCount != nil || probe.ProviderSummary != nil || probe.OnlineCount != nil || probe.OfflineCount != nil {\n\t\t\treturn validatedRuntimeProbe{}, errors.New(\"failed runtime probes must not include counts\")\n\t\t}\n\t\treturn validated, nil\n\t}\n\n\tif probe.RuntimeCount == nil || probe.ProviderSummary == nil || probe.OnlineCount == nil || probe.OfflineCount == nil {\n\t\treturn validatedRuntimeProbe{}, errors.New(\"successful runtime probes require all counts\")\n\t}\n\tif *probe.RuntimeCount < 0 || *probe.RuntimeCount > 1000 || *probe.OnlineCount < 0 || *probe.OfflineCount < 0 || *probe.OnlineCount+*probe.OfflineCount != *probe.RuntimeCount {\n\t\treturn validatedRuntimeProbe{}, errors.New(\"invalid runtime counts\")\n\t}\n\tif len(probe.ProviderSummary) > 32 {\n\t\treturn validatedRuntimeProbe{}, errors.New(\"too many runtime providers\")\n\t}","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/multica-ai/multica/blob/2c0912b6ec764b373d44eeea1e80f0d9f11ab417/server/internal/handler/client_usage.go#L171-L207","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Send exactly \"success\" or \"error\" (case-insensitive) in probe_result.","Map any local richer outcome (timeout, partial) to 'error' client-side before reporting.","Centralize the allowed values in a shared constant/enum used by both client and server.","Add a client-side unit test asserting emitted probe_result ∈ {success, error}."],"exampleFix":"// before\n{\"probe_result\": probe.timedOut ? \"timeout\" : \"success\"}\n\n// after\n{\"probe_result\": probe.timedOut ? \"error\" : \"success\"}","handlingStrategy":"validation","validationCode":"const PROBE_RESULTS = new Set(['success', 'error']);\n\nfunction normalizeProbeResult(raw) {\n  const v = String(raw ?? '').trim().toLowerCase();\n  if (!PROBE_RESULTS.has(v)) {\n    throw new TypeError(`probe_result must be 'success' or 'error', got ${JSON.stringify(raw)}`);\n  }\n  return v;\n}","typeGuard":"const isProbeResult = (v) => v === 'success' || v === 'error';","tryCatchPattern":null,"preventionTips":["Define the enum in one shared module imported by every probe-reporting code path.","Collapse richer local outcomes (timeout/partial/unknown) to 'error' at the reporting boundary.","Contract-test the daemon's emitted payload against the server's validator on CI."],"tags":["validation","telemetry","enum","http-400"],"backgroundTag":null,"analyzedSha":"2c0912b6ec764b373d44eeea1e80f0d9f11ab417","analyzedAt":"2026-08-15T13:25:18.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}