{"record":{"id":"16a2cf93adbb2493","repo":"koala73/worldmonitor","slug":"markpickcomplete-no-run-args-runid","errorCode":null,"errorMessage":"[_markPickComplete] no run ${args.runId}","messagePattern":"\\[_markPickComplete\\] no run (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"convex/broadcast/waveRuns.ts","lineNumber":602,"sourceCode":"});\n\n/**\n * Transition a `picking`-status run to `segment-created` after pickWaveAction\n * has finished sampling, persisting, and creating the Resend segment.\n */\nexport const _markPickComplete = internalMutation({\n  args: {\n    runId: v.string(),\n    segmentId: v.string(),\n    totalCount: v.number(),\n    underfilled: v.boolean(),\n  },\n  handler: async (ctx, args) => {\n    const run = await ctx.db\n      .query(\"waveRuns\")\n      .withIndex(\"by_runId\", (q) => q.eq(\"runId\", args.runId))\n      .unique();\n    if (!run) throw new Error(`[_markPickComplete] no run ${args.runId}`);\n    if (run.status !== \"picking\") {\n      throw new Error(\n        `[_markPickComplete] run ${args.runId} is ${run.status}, expected picking`,\n      );\n    }\n    const now = Date.now();\n    await ctx.db.patch(run._id, {\n      status: \"segment-created\",\n      segmentId: args.segmentId,\n      totalCount: args.totalCount,\n      underfilled: args.underfilled,\n      updatedAt: now,\n    });\n    return { ok: true };\n  },\n});\n\n/**","sourceCodeStart":584,"sourceCodeEnd":620,"githubUrl":"https://github.com/koala73/worldmonitor/blob/ffec79ac339946fd2d24e85845da5755dcaa534b/convex/broadcast/waveRuns.ts#L584-L620","documentation":"Thrown by _markPickComplete when no waveRuns row matches the provided runId. Like _recordPoolFilterStats, this indicates the run row is missing — the caller (pickWaveAction) should only call this after a successful pick phase on a run it already claimed. The row is created by _claimWaveRunLease at the start of the pipeline.","triggerScenarios":"pickWaveAction calls _markPickComplete with a runId whose row was deleted mid-flight (discardWaveRun or manual DB delete). The runId passed does not match the one returned by _claimWaveRunLease. A test calls _markPickComplete without first creating the run row.","commonSituations":"The operator discarded the wave run while pickWaveAction was still executing. A developer refactored pickWaveAction and introduced a runId mismatch. Parallel or replayed scheduled actions reference a stale runId.","solutions":["Verify the runId passed to _markPickComplete matches the runId from _claimWaveRunLease in the same pickWaveAction invocation.","Check whether discardWaveRun removed the row — if so, treat the run as cancelled and stop the pipeline.","In tests, insert a waveRuns row with status 'picking' before calling _markPickComplete."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["In pickWaveAction, pass the exact runId from _claimWaveRunLease to _markPickComplete.","Do not discard the wave run while pickWaveAction is still executing.","In tests, insert a waveRuns row with status 'picking' before calling _markPickComplete."],"tags":["convex","state-machine","wave-runs","logic-bug","internal-mutation"],"backgroundTag":null,"analyzedSha":"ffec79ac339946fd2d24e85845da5755dcaa534b","analyzedAt":"2026-08-12T11:24:56.012Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}