koala73/worldmonitor · error · Error

[_persistPickedBatch] chunk too large

Error message

[_persistPickedBatch] chunk too large: ${contacts.length} > ${PERSIST_CHUNK_SIZE}

What it means

Chunk-size guard in _persistPickedBatch: the caller passed more picked contacts than PERSIST_CHUNK_SIZE in one mutation. Chunking exists to stay under Convex per-mutation write limits; an oversized batch would exceed them, so it is rejected before any insert.

Solutions

  1. Split the batch into chunks of at most PERSIST_CHUNK_SIZE contacts before calling the mutation
  2. Fix the batching loop in pickWaveAction so it never assembles an oversized chunk
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at convex/broadcast/waveRuns.ts:564 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/f9fad5ed9c5b49da. Report an issue: GitHub.

Appendix: source

Thrown at convex/broadcast/waveRuns.ts:580

      createdAt: now,
      updatedAt: now,
    });
    return { ok: true, runId: args.runId };
  },
});

/**
 * Insert a chunk of picked-contact rows. Called repeatedly from
 * `pickWaveAction` to stay under Convex per-mutation write limits.
 */
export const _persistPickedBatch = internalMutation({
  args: {
    runId: v.string(),
    contacts: v.array(v.string()), // normalizedEmails
  },
  handler: async (ctx, { runId, contacts }) => {
    if (contacts.length > PERSIST_CHUNK_SIZE) {
      throw new Error(
        `[_persistPickedBatch] chunk too large: ${contacts.length} > ${PERSIST_CHUNK_SIZE}`,
      );
    }
    const now = Date.now();
    for (const email of contacts) {
      await ctx.db.insert("wavePickedContacts", {
        runId,
        normalizedEmail: email,
        status: "pending",
      });
    }
    // Bump updatedAt so the in-flight guard's lastActivityAt fallback sees fresh activity.
    const run = await ctx.db
      .query("waveRuns")
      .withIndex("by_runId", (q) => q.eq("runId", runId))
      .unique();
    if (run) await ctx.db.patch(run._id, { updatedAt: now });
    return { inserted: contacts.length };

View on GitHub (pinned to 7d06c8633d)