koala73/worldmonitor · error · Error

[runDailyRamp] rampCurve

Error message

[runDailyRamp] rampCurve[${nextTier}] is undefined despite bounds check — config corruption?

What it means

Defensive invariant guard in runDailyRamp: rampCurve[nextTier] is undefined even though the nextTier < rampCurve.length bounds check just passed. This should be unreachable and indicates the persisted broadcastRampConfig.rampCurve array is corrupted — mutated between the check and the access, or written with holes.

Solutions

  1. Inspect the broadcastRampConfig document's rampCurve array for holes, non-numeric entries, or concurrent modification
  2. Re-run configureRamp to rewrite a clean rampCurve and resume the ramp
  3. Add a validation step in configureRamp that rejects sparse or malformed rampCurve arrays before they persist
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at convex/broadcast/rampRunner.ts:1025 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/e9727c4f5a77917d. Report an issue: GitHub.

Appendix: source

Thrown at convex/broadcast/rampRunner.ts:1027

      }
    }

    // ──── Step 2: figure out which tier to send next ────
    const nextTier = row.currentTier + 1;
    if (nextTier >= row.rampCurve.length) {
      console.log("[runDailyRamp] ramp curve complete — deactivating");
      await ctx.runMutation(
        internal.broadcast.rampRunner._recordRunOutcome,
        { status: "ramp-complete", deactivate: true },
      );
      return { status: "ramp-complete" };
    }
    // Bounds-checked above; explicit guard quiets noUncheckedIndexedAccess
    // and protects against a future code change that breaks the
    // bounds check above without realising this index is now unsafe.
    const count = row.rampCurve[nextTier];
    if (count === undefined) {
      throw new Error(
        `[runDailyRamp] rampCurve[${nextTier}] is undefined despite bounds check — config corruption?`,
      );
    }
    const waveLabel = `${row.waveLabelPrefix}-${nextTier + row.waveLabelOffset}`;

    // ──── Step 3: in-flight guard via the new wave-loading state machine ────
    // PR 2 (post-launch-stabilization plan, 2026-04-29) replaces the
    // monolithic assignAndExportWave + createProLaunchBroadcast + sendProLaunchBroadcast
    // chain with a self-driving multi-step pipeline that fits within the
    // Convex 10-min action runtime budget at any wave size. The state lives
    // on `waveRuns` + `wavePickedContacts`. See `convex/broadcast/waveRuns.ts`.
    //
    // The legacy `_claimTierForRun` + `_recordPendingExport` + `_recordPendingBroadcast`
    // + `_recordWaveSent` + `_recordRunOutcome` mutations remain in this
    // module so the operator-recovery commands (`recoverFromPartialFailure`,
    // `clearPartialFailure`, `forceReleaseLease`) keep working on any
    // legacy partial-failure rows. New runs go through the state machine.
    //

View on GitHub (pinned to 7d06c8633d)