musistudio/claude-code-router · warning

[fusion-vision] Failed to publish lightweight usage event

Error message

[fusion-vision] Failed to publish lightweight usage event: ${formatError(lastError)}

What it means

The fusion-vision MCP tried multiple times to publish a lightweight usage event to the remote usage sync endpoint and every attempt failed; after retries exhausted it logs the last error once (guarded by a flag) and gives up. Usage telemetry for that event is lost but the MCP continues functioning.

Solutions

  1. Check network connectivity and proxy settings from the host to the usage endpoint
  2. Inspect the formatted error for HTTP status (401/403 = credentials, 5xx = upstream outage) and fix accordingly
  3. If telemetry is intentionally blocked, suppress the warning or disable usage sync in config to avoid retry churn

Example fix

// before: no proxy configured, egress blocked
// after: route via corporate proxy
process.env.HTTPS_PROXY = "http://proxy.corp:8080";
process.env.HTTP_PROXY = "http://proxy.corp:8080";
Defensive patterns

Strategy: retry

Validate before calling

await fetch(usageEndpoint, { method: "HEAD" }).catch(() => { throw new Error("Usage endpoint unreachable"); });

Try / catch

try { await publishUsageEvent(event); } catch { /* telemetry is best-effort: log once, never fail the MCP call */ }

Prevention

When it happens

Trigger: Network egress blocked to the usage endpoint; endpoint returning 5xx or auth failures across all retry attempts; proxy/DNS misconfiguration in the environment running the MCP.

Common situations: Corporate proxies blocking the telemetry host; expired credentials for the usage service; transient outage longer than the retry budget (exponential backoff exhausted).

Related errors


AI-assisted analysis of musistudio/claude-code-router@99f24806c6 (2026-08-27). Data as JSON: /api/errors/80230fb6117c22ef. Report an issue: GitHub.

Appendix: source

Thrown at packages/core/src/mcp/fusion-vision-mcp.ts:434

      }
      const acknowledgement = rawBody ? parseJson(rawBody) : undefined;
      if (isRecord(acknowledgement) && acknowledgement.applied === false) {
        throw new FusionUsageSyncRejectedError();
      }
      usageSyncFailureLogged = false;
      return;
    } catch (error) {
      lastError = error;
      if (attempt >= fusionUsageSyncMaxAttempts || !usageSyncErrorIsRetryable(error)) {
        break;
      }
      await wait(fusionUsageSyncBaseDelayMs * 2 ** (attempt - 1));
    }
  }

  if (!usageSyncFailureLogged) {
    usageSyncFailureLogged = true;
    console.warn(`[fusion-vision] Failed to publish lightweight usage event: ${formatError(lastError)}`);
  }
}

class FusionUsageSyncHttpError extends Error {
  readonly retryable: boolean;

  constructor(readonly statusCode: number) {
    super(`HTTP ${statusCode}`);
    this.name = "FusionUsageSyncHttpError";
    this.retryable = statusCode === 408 || statusCode === 409 || statusCode === 425 || statusCode === 429 || statusCode >= 500;
  }
}

class FusionUsageSyncRejectedError extends Error {
  readonly retryable = false;

  constructor() {
    super("Usage sync endpoint rejected the event.");

View on GitHub (pinned to 99f24806c6)