koala73/worldmonitor · error · ConvexError

email required for email channel

Error message

email required for email channel

What it means

Channel-shape validation in setChannel: channelType is 'email' but args.email is missing. Email channels store the delivery address as their payload, so the channel document cannot be created without it.

Solutions

  1. Collect and submit the email address with the channel settings
  2. Require the email field in the UI when email is the selected channel type
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at convex/notificationChannels.ts:509 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of koala73/worldmonitor@e586b8b4b8 (2026-08-21). Data as JSON: /api/errors/161e8498a5277490. Report an issue: GitHub.

Appendix: source

Thrown at convex/notificationChannels.ts:540

    const existing = await ctx.db
      .query("notificationChannels")
      .withIndex("by_user_channel", (q) =>
        q.eq("userId", userId).eq("channelType", args.channelType),
      )
      .unique();

    const now = Date.now();

    if (args.channelType === "telegram") {
      throw new ConvexError("telegram channel must be linked through bot pairing");
    } else if (args.channelType === "slack") {
      if (!args.webhookEnvelope) throw new ConvexError("webhookEnvelope required for slack channel");
      const doc = { userId, channelType: "slack" as const, webhookEnvelope: args.webhookEnvelope, verified: true, linkedAt: now };
      if (existing) {
        await ctx.db.replace(existing._id, doc);
      } else {
        await ctx.db.insert("notificationChannels", doc);
      }
    } else if (args.channelType === "email") {
      const email = requireVerifiedAccountEmail(args.email, identity.emailVerified === true ? identity.email : undefined);
      const doc = { userId, channelType: "email" as const, email, emailOwnership: "verified_account" as const, verified: true, linkedAt: now };
      if (existing) {
        await ctx.db.replace(existing._id, doc);
      } else {
        await ctx.db.insert("notificationChannels", doc);
      }
    } else if (args.channelType === "webhook") {
      if (!args.webhookEnvelope) throw new ConvexError("webhookEnvelope required for webhook channel");
      const doc = { userId, channelType: "webhook" as const, webhookEnvelope: args.webhookEnvelope, verified: true, linkedAt: now, webhookLabel: args.webhookLabel };
      if (existing) {
        await ctx.db.replace(existing._id, doc);
      } else {
        await ctx.db.insert("notificationChannels", doc);
      }
    } else {
      throw new ConvexError("discord channel must be set via set-discord-oauth");

View on GitHub (pinned to e586b8b4b8)