{"record":{"id":"9da987c84741c550","repo":"koala73/worldmonitor","slug":"recoverfrompartialfailure-manual-finished-curren","errorCode":null,"errorMessage":"[recoverFromPartialFailure:manual-finished] currentTier=${row.currentTier} would advance past rampCurve.length=${row.rampCurve.length}. Curve is complete; nothing to recover.","messagePattern":"\\[recoverFromPartialFailure:manual-finished\\] currentTier=(.+?) would advance past rampCurve\\.length=(.+?)\\. Curve is complete; nothing to recover\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"convex/broadcast/rampRunner.ts","lineNumber":399,"sourceCode":"      pendingRunId: undefined,\n      pendingRunStartedAt: undefined,\n      pendingWaveLabel: undefined,\n      pendingSegmentId: undefined,\n      pendingAssigned: undefined,\n      pendingExportAt: undefined,\n      pendingBroadcastId: undefined,\n      pendingBroadcastAt: undefined,\n    } as const;\n\n    if (args.recovery === \"manual-finished\") {\n      // Resolve each field: operator-supplied wins, persisted pending* is the\n      // fallback. sentAt is operator-only (no fallback).\n      const broadcastId = args.broadcastId ?? row.pendingBroadcastId;\n      const segmentId = args.segmentId ?? row.pendingSegmentId;\n      const assigned = args.assigned ?? row.pendingAssigned;\n      const nextTier = row.currentTier + 1;\n      if (nextTier >= row.rampCurve.length) {\n        throw new Error(\n          `[recoverFromPartialFailure:manual-finished] currentTier=${row.currentTier} would advance past rampCurve.length=${row.rampCurve.length}. Curve is complete; nothing to recover.`,\n        );\n      }\n      const waveLabel =\n        args.waveLabel ??\n        row.pendingWaveLabel ??\n        `${row.waveLabelPrefix}-${nextTier + row.waveLabelOffset}`;\n\n      const missing: string[] = [];\n      if (!broadcastId) missing.push(\"broadcastId\");\n      if (!segmentId) missing.push(\"segmentId\");\n      if (assigned === undefined) missing.push(\"assigned\");\n      if (args.sentAt === undefined) missing.push(\"sentAt\");\n      if (missing.length > 0) {\n        throw new Error(\n          `[recoverFromPartialFailure:manual-finished] missing required field(s): ${missing.join(\", \")}. ` +\n            `Operator must supply (or rely on persisted pending* state from a prior runner). Persisted state: ` +\n            `pendingBroadcastId=${row.pendingBroadcastId ?? \"-\"}, pendingSegmentId=${row.pendingSegmentId ?? \"-\"}, ` +","sourceCodeStart":381,"sourceCodeEnd":417,"githubUrl":"https://github.com/koala73/worldmonitor/blob/7d06c8633d256c18e38133030bc3613976a96ec9/convex/broadcast/rampRunner.ts#L381-L417","documentation":"Error \"[recoverFromPartialFailure:manual-finished] currentTier=${row.currentTier} would advance past rampCurve.length=${row.rampCurve.length}. Curve is complete; nothing to recover.\" thrown in koala73/worldmonitor.","triggerScenarios":"Thrown at convex/broadcast/rampRunner.ts:399 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Treat as terminal success — the ramp curve is fully sent; no further waves exist to recover","If more waves are genuinely needed, configure a new ramp with an extended rampCurve rather than forcing recovery past the end"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"7d06c8633d256c18e38133030bc3613976a96ec9","analyzedAt":"2026-08-21T16:51:25.751Z","contentChangedAt":"2026-08-21T16:51:25.751Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}