koala73/worldmonitor · error · Error

[_finalizeWaveRun] run ${runId} is ${run.status}, expected b

Error message

[_finalizeWaveRun] run ${runId} is ${run.status}, expected broadcast-created

What it means

State-machine guard in _finalizeWaveRun: the run's status is not 'broadcast-created' (the actual status is embedded). Only a run whose broadcast was created may finalize to 'sent'; note that 'sent' is handled earlier as an idempotent no-op, so this throw means a genuinely unexpected status such as 'picking' or 'failed'.

Source

Thrown at convex/broadcast/waveRuns.ts:1420

    sentAt: v.number(),
  },
  handler: async (ctx, { runId, sentAt }) => {
    const run = await ctx.db
      .query("waveRuns")
      .withIndex("by_runId", (q) => q.eq("runId", runId))
      .unique();
    if (!run) throw new Error(`[_finalizeWaveRun] no run ${runId}`);

    // Status check FIRST — broadcastId presence is downstream of being in
    // broadcast-created status. Checking presence before status would mask
    // a wrong-status caller behind a misleading "missing broadcastId" error.
    if (run.status === "sent") {
      // Idempotent: a duplicate finalize on an already-sent run is a no-op,
      // not an error. Don't re-advance the tier.
      return { ok: true as const, alreadySent: true as const, advancedToTier: undefined };
    }
    if (run.status !== "broadcast-created") {
      throw new Error(
        `[_finalizeWaveRun] run ${runId} is ${run.status}, expected broadcast-created`,
      );
    }
    if (!run.broadcastId || !run.segmentId) {
      throw new Error(
        `[_finalizeWaveRun] run ${runId} missing broadcastId/segmentId`,
      );
    }

    const config = await ctx.db
      .query("broadcastRampConfig")
      .withIndex("by_key", (q) => q.eq("key", "current"))
      .unique();
    if (!config) throw new Error("[_finalizeWaveRun] no broadcastRampConfig");
    if (config.pendingRunId !== runId) {
      throw new Error(
        `[_finalizeWaveRun] lost lease: expected ${runId}, found ${config.pendingRunId ?? "<cleared>"}. ` +
        `Refusing to advance tier — operator force-released the lease, or another run took over.`,

View on GitHub (pinned to eeab0a219f)

Solutions

  1. Read the embedded status: 'picking' or 'segment-created' means finalize ran before broadcast creation completed — re-run the finalize step in order
  2. 'failed' means the run was marked failed; recover via the documented recovery flow rather than forcing finalize
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at convex/broadcast/waveRuns.ts:1420 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of koala73/worldmonitor@eeab0a219f (2026-08-21). Data as JSON: /api/errors/2edba46cc1f0cb68. Report an issue: GitHub.