koala73/worldmonitor · error · Error
[pauseRamp] no ramp configured
Error message
[pauseRamp] no ramp configured
What it means
pauseRamp is a Convex internalMutation that sets broadcastRampConfig.active=false. It reads the singleton config row via loadConfig(ctx), which queries the broadcastRampConfig table by key='current'. If no row exists the handler throws rather than no-op'ing, so an operator cannot silently 'pause' a ramp that was never seeded and believe it took effect.
Source
Thrown at convex/broadcast/rampRunner.ts:223
lastWaveBroadcastId: args.seedLastWaveBroadcastId,
lastWaveSentAt: args.seedLastWaveSentAt,
lastWaveLabel: args.seedLastWaveLabel,
lastWaveSegmentId: args.seedLastWaveSegmentId,
lastWaveAssigned: args.seedLastWaveAssigned,
// Default-FALSE on insert when arg omitted. Per the design doc:
// explicit, never silently true — existing-ramp byte-identical
// behavior is the default; operators opt in for wave-8+.
excludeNonEnglish: args.excludeNonEnglish ?? false,
});
return { ok: true };
},
});
export const pauseRamp = internalMutation({
args: {},
handler: async (ctx) => {
const row = await loadConfig(ctx);
if (!row) throw new Error("[pauseRamp] no ramp configured");
await ctx.db.patch(row._id, { active: false });
return { ok: true, prevActive: row.active };
},
});
export const resumeRamp = internalMutation({
args: {},
handler: async (ctx) => {
const row = await loadConfig(ctx);
if (!row) throw new Error("[resumeRamp] no ramp configured");
if (row.killGateTripped) {
throw new Error(
"[resumeRamp] kill-gate is tripped; clearKillGate first after investigating.",
);
}
await ctx.db.patch(row._id, { active: true });
return { ok: true };
},View on GitHub (pinned to ffec79ac33)
Solutions
- Preflight with getRampStatus; if it returns {configured:false}, run initRamp first to seed the config row.
- If the ramp was aborted, re-run initRamp with the original rampCurve and seedLastWave* fields to recreate the row, then pauseRamp.
- Confirm the calling client/cron targets the correct Convex deployment (CONVEX_DEPLOYMENT / VITE_CONVEX_URL) that holds the seeded config.
Example fix
// before
await ctx.runMutation(internal.broadcast.rampRunner.pauseRamp, {});
// after
const status = await ctx.runQuery(internal.broadcast.rampRunner.getRampStatus, {});
if (!status.configured) throw new Error('Cannot pause: ramp not configured. Run initRamp first.');
await ctx.runMutation(internal.broadcast.rampRunner.pauseRamp, {}); Defensive patterns
Strategy: validation
Validate before calling
// Preflight before pauseRamp
const status = await ctx.runQuery(internal.broadcast.rampRunner.getRampStatus, {});
if (!status.configured) {
throw new Error('Ramp not configured — run initRamp before pauseRamp.');
} Type guard
type RampStatus =
| { configured: false }
| { configured: true; active: boolean; killGateTripped: boolean; currentTier: number; rampCurve: number[] };
function isConfigured(s: RampStatus): s is Extract<RampStatus, { configured: true }> {
return s.configured === true;
} Prevention
- Always preflight admin mutations with getRampStatus and branch on .configured.
- Seed every Convex deployment (dev/preview/prod) with initRamp as part of provisioning.
- Make pauseRamp calls idempotent in runbooks by checking status first.
When it happens
Trigger: Calling the pauseRamp mutation before initRamp has ever run; calling it after abortRamp (which deletes the row); calling it from a cron/automation in a fresh Convex deployment or preview that was never seeded.
Common situations: New or staging Convex project that was never initialized; CI pointing at the wrong CONVEX_DEPLOYMENT; an operator ran abortRamp during incident triage and a still-scheduled job fires pauseRamp afterward.
Related errors
- [resumeRamp] no ramp configured
- [clearKillGate] no ramp configured
- [clearPartialFailure] no ramp configured
- [recoverFromPartialFailure] no ramp configured
- [recoverFromPartialFailure:manual-finished] currentTier=${ro
AI-assisted analysis of koala73/worldmonitor@ffec79ac33 (2026-08-12).
Data as JSON: /api/errors/95319139fd6ad688.
Report an issue: GitHub.