koala73/worldmonitor · error · Error

[clearKillGate] no ramp configured

Error message

[clearKillGate] no ramp configured

What it means

clearKillGate resets broadcastRampConfig.killGateTripped=false and clears the reason. It loads the singleton config via loadConfig and throws if no row exists, so clearing a gate on a non-existent ramp cannot silently succeed.

Source

Thrown at convex/broadcast/rampRunner.ts:248

  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 };
  },
});

export const clearKillGate = internalMutation({
  args: { reason: v.string() },
  handler: async (ctx, { reason }) => {
    const row = await loadConfig(ctx);
    if (!row) throw new Error("[clearKillGate] no ramp configured");
    if (!row.killGateTripped) {
      return { ok: true, noop: true };
    }
    await ctx.db.patch(row._id, {
      killGateTripped: false,
      killGateReason: undefined,
      lastRunStatus: `kill-gate-cleared: ${reason.slice(0, 200)}`,
    });
    return { ok: true };
  },
});

/**
 * Last-resort soft-clear of a `partial-failure` status. STRONGLY DISPREFERRED;
 * use `recoverFromPartialFailure` instead in nearly every case.
 *
 * Naive clear is RISKY when the export already succeeded. Concrete failure
 * shape: `assignAndExportWave` stamped contacts with `waveLabel` AND created

View on GitHub (pinned to ffec79ac33)

Solutions

  1. Preflight with getRampStatus; if {configured:false} there is no gate to clear — abort the runbook step.
  2. If the config is intentionally gone, no action is needed (abortRamp already removed the tripped state).
  3. Re-seed via initRamp if a new ramp is intended, then re-evaluate the gate.

Example fix

// before
await ctx.runMutation(internal.broadcast.rampRunner.clearKillGate, { reason });

// after
const status = await ctx.runQuery(internal.broadcast.rampRunner.getRampStatus, {});
if (!status.configured) return { skipped: 'no ramp configured — nothing to clear' };
await ctx.runMutation(internal.broadcast.rampRunner.clearKillGate, { reason });
Defensive patterns

Strategy: validation

Validate before calling

// Preflight before clearKillGate
const status = await ctx.runQuery(internal.broadcast.rampRunner.getRampStatus, {});
if (!status.configured) {
  return { skipped: 'no ramp configured — nothing to clear' };
}

Type guard

function isConfigured(s: { configured: boolean }): s is { configured: true } {
  return s.configured === true;
}

Prevention

When it happens

Trigger: Calling clearKillGate before initRamp, after abortRamp deleted the row, or against an unseeded Convex deployment.

Common situations: The ramp was aborted during incident triage but a recovery runbook step still calls clearKillGate; tooling pointed at the wrong Convex project.

Related errors


AI-assisted analysis of koala73/worldmonitor@ffec79ac33 (2026-08-12). Data as JSON: /api/errors/d8dde0a51f7f9f66. Report an issue: GitHub.