koala73/worldmonitor · error · Error

[_recordWaveSent] no ramp configured

Error message

[_recordWaveSent] no ramp configured

What it means

Internal guard in the _recordWaveSent mutation: loadConfig returned no broadcastRampConfig row, so the successful send cannot be recorded and the tier cannot advance. Runner-internal invariant failure — the config existed when the action started, so it was deleted mid-flight or the environment is wrong.

Solutions

  1. Check whether broadcastRampConfig was deleted or reset while the wave was being sent
  2. Manually record the send (broadcastId, sentAt) and reconcile tier state before restarting the ramp
Defensive patterns

Strategy: validation

When it happens

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

Common situations: See trigger scenarios.


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

Appendix: source

Thrown at convex/broadcast/rampRunner.ts:784

/**
 * Internal mutation that the action calls to atomically advance the tier +
 * record a successful wave-send. Validates that the lease still belongs to
 * this runId AND clears all pending-progress markers.
 */
export const _recordWaveSent = internalMutation({
  args: {
    runId: v.string(),
    expectedCurrentTier: v.number(),
    newTier: v.number(),
    waveLabel: v.string(),
    broadcastId: v.string(),
    segmentId: v.string(),
    assigned: v.number(),
    sentAt: v.number(),
  },
  handler: async (ctx, args) => {
    const row = await loadConfig(ctx);
    if (!row) throw new Error("[_recordWaveSent] no ramp configured");
    if (row.currentTier !== args.expectedCurrentTier) {
      throw new Error(
        `[_recordWaveSent] tier moved underneath us: expected ${args.expectedCurrentTier}, found ${row.currentTier}. Refusing to overwrite.`,
      );
    }
    if (row.pendingRunId !== args.runId) {
      // The lease changed under us — operator force-released it, or
      // recoverFromPartialFailure cleared it. We must NOT advance the tier;
      // bubble to Convex auto-Sentry so ops can investigate.
      throw new Error(
        `[_recordWaveSent] lease lost: expected runId=${args.runId}, found ${row.pendingRunId ?? "<cleared>"}. Refusing to advance tier — investigate what cleared the lease.`,
      );
    }
    await ctx.db.patch(row._id, {
      currentTier: args.newTier,
      lastWaveLabel: args.waveLabel,
      lastWaveBroadcastId: args.broadcastId,
      lastWaveSegmentId: args.segmentId,

View on GitHub (pinned to 7d06c8633d)