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
- Read the embedded status: 'picking' or 'segment-created' means finalize ran before broadcast creation completed — re-run the finalize step in order
- '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.