SG.devS
Convex Community16mo ago
2 replies
SG.dev

Issue with Canceling a Scheduled Task – How to Retrieve and Pass Task ID to Frontend

I'm trying to implement a feature where users can schedule a deletion task and cancel it from the frontend, but I'm getting TS errors trying to return the taskId from a mutation:

export const scheduledDelete = mutation({
  args: { id: v.id("thing") },
  handler: async (ctx, args) => {
    const userId = await getUserId(ctx);
    const thing = await ctx.db.get(args.id);

    if (!thing) throw new Error(`Dream with ID ${args.id} not found.`);
    if (userId !== thing.userId) throw new Error("Unauthorized access.");

    const taskId = await ctx.scheduler.runAfter(
      10 * 1000,
      internal.mutations.deleteThing,
      { id: thing._id }
    );

    return taskId;
  },
});

export const deleteThing = internalMutation({
  args: { id: v.id("thing") },
  handler: async (ctx, args) => {
    await ctx.db.delete(args.id);
  },
});

export const cancelScheduledDeletion = mutation({
  args: { taskId: v.id("_scheduled_functions") },
  handler: async (ctx, args) => {
    await ctx.scheduler.cancel(args.taskId);
  },
});

'scheduledDelete' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
'handler' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.


- What is the recommended way to pass the scheduled task ID to the frontend so the user can cancel the task later?
- Should the task ID be stored in the database instead, or is there a way to return it safely from the mutation?
- Are there any examples or patterns recommended by the Convex team for handling cancelable scheduled tasks from the frontend?
Was this page helpful?