koala73/worldmonitor · error · Error
[forceReleaseLease] no ramp configured
Error message
[forceReleaseLease] no ramp configured
What it means
Operator guard in the forceReleaseLease internal mutation: loadConfig returned no broadcastRampConfig row, so there is no lease to force-release. The last-resort wedge-recovery tool cannot run because the ramp was never configured on this deployment.
Solutions
- Run configureRamp before using lease-recovery tooling
- Confirm the deployment actually has a ramp — a missing config row usually means wrong environment
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at convex/broadcast/rampRunner.ts:670 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/c2ff16c7dc2ffbcd.
Report an issue: GitHub.
Appendix: source
Thrown at convex/broadcast/rampRunner.ts:672
/**
* Operator-only last-resort lease release.
*
* Use ONLY when a cron action is genuinely wedged (process died silently
* between claim and any catch block, leaving a held lease with no
* partial-failure status). Investigate Convex action logs + Resend dashboard
* BEFORE calling this — the side effects might have actually completed
* (segment created, broadcast sent) and the right recovery is then
* `recoverFromPartialFailure({recovery:"manual-finished"})`, not a fresh send.
*
* Sets `lastRunStatus = "partial-failure"` so `recoverFromPartialFailure`
* picks up; preserves any `pending*` progress markers so the operator can
* decide between manual-finished and discard-and-rotate from persisted state.
*/
export const forceReleaseLease = internalMutation({
args: { reason: v.string() },
handler: async (ctx, { reason }) => {
const row = await loadConfig(ctx);
if (!row) throw new Error("[forceReleaseLease] no ramp configured");
if (!row.pendingRunId) {
return {
ok: true as const,
noop: true as const,
currentStatus: row.lastRunStatus,
};
}
const releasedRunId = row.pendingRunId;
const heldForMs =
row.pendingRunStartedAt !== undefined
? Date.now() - row.pendingRunStartedAt
: undefined;
await ctx.db.patch(row._id, {
pendingRunId: undefined,
pendingRunStartedAt: undefined,
lastRunStatus: "partial-failure",
lastRunAt: Date.now(),
lastRunError: `forced-release: ${reason.slice(0, 200)} (was held by ${releasedRunId}${heldForMs !== undefined ? `, age ${Math.round(heldForMs / 1000)}s` : ""})`,View on GitHub (pinned to 7d06c8633d)