# Convex Mutations

> This skill should be used when implementing Convex mutation functions. It provides comprehensive guidelines for defining, registering, calling, and scheduling mutations, including database operations, transactions, and scheduled job patterns.

- Skill: `majiayu000/convex-mutations` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds add majiayu000/convex-mutations`
- Raw SKILL.md: https://api.skillmd.com/api/skills/majiayu000/convex-mutations/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: majiayu000 (https://skillmd.com/u/majiayu000)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/majiayu000/convex-mutations

---


# Convex Mutations Skill

This skill provides specialized guidance for implementing Convex mutation functions, including best practices for function definition, registration, database operations, and scheduling patterns.

## When to Use This Skill

Use this skill when:
- Defining new mutation functions to write or modify data in the Convex database
- Performing database operations (`insert`, `patch`, `replace`, `delete`)
- Calling mutations from other Convex functions
- Scheduling future mutations with `ctx.scheduler.runAfter`
- Handling transactional operations
- Coordinating mutations with actions for background processing

## Skill Resources

This skill includes comprehensive reference documentation in `references/mutation-guidelines.md` that covers:

### Core Mutation Development
- Function definition syntax using the new function syntax
- Mutation registration (`mutation` and `internalMutation`)
- Argument validators and their usage
- Function calling patterns (`ctx.runQuery` and `ctx.runMutation`)
- Function references (`api` and `internal` objects)
- File-based routing for mutation paths

### Database Operations
- `ctx.db.insert()` - Create new documents
- `ctx.db.patch()` - Shallow merge updates into existing documents
- `ctx.db.replace()` - Fully replace existing documents
- Error handling for missing documents
- Transaction semantics and consistency guarantees

### Advanced Mutation Features
- **Scheduling**: Using `ctx.scheduler.runAfter()` to queue background jobs
  - Scheduling mutations and actions for future execution
  - Understanding that auth state does NOT propagate to scheduled jobs
  - Using internal functions for scheduled jobs that need privileges
  - Avoiding tight loops and respecting 10-second minimum intervals
- **Transactional Behavior**: Understanding mutation transactions
  - Enqueuing scheduler jobs is transactional within mutations
  - Race condition prevention through transaction boundaries

### Function Composition
- Calling queries within mutations for validation
- Calling mutations from mutations
- Using return type annotations for same-file mutation calls

## How to Use This Skill

1. **Read the reference documentation** at `references/mutation-guidelines.md` to understand the complete mutation patterns
2. **Follow the syntax examples** for defining mutation functions with proper validators
3. **Use appropriate database operations** (`insert`, `patch`, `replace`) based on your needs
4. **Schedule background work** using `ctx.scheduler.runAfter` for long-running operations
5. **Remember auth state does NOT propagate** to scheduled jobs; use internal functions for privileged operations
6. **Leverage transactions** for consistency across multiple operations

## Key Mutation Guidelines

- ALWAYS include argument validators for all mutation functions
- Use `ctx.db.patch()` for partial updates and `ctx.db.replace()` for full replacements
- Use `ctx.scheduler.runAfter()` to schedule actions (e.g., AI responses, notifications)
- Remember that scheduled jobs have `null` auth state; use internal functions instead
- Mutations execute for at most 1 second and can write up to 8192 documents
- Return `null` implicitly if your mutation doesn't have an explicit return value
- Use return type annotations when calling mutations in the same file (TypeScript circularity workaround)

## Example: Mutation with Database Operation and Scheduling

```ts
import { mutation, internalAction } from "./_generated/server";
import { v } from "convex/values";
import { internal } from "./_generated/api";

export const sendMessage = mutation({
  args: {
    channelId: v.id("channels"),
    authorId: v.id("users"),
    content: v.string(),
  },
  handler: async (ctx, args) => {
    // Validate channel and user exist
    const channel = await ctx.db.get(args.channelId);
    if (!channel) {
      throw new Error("Channel not found");
    }

    // Insert message into database
    await ctx.db.insert("messages", {
      channelId: args.channelId,
      authorId: args.authorId,
      content: args.content,
    });

    // Schedule AI response generation (transactional)
    await ctx.scheduler.runAfter(0, internal.functions.generateResponse, {
      channelId: args.channelId,
    });

    return null;
  },
});

export const updateUserStatus = mutation({
  args: {
    userId: v.id("users"),
    status: v.string(),
  },
  handler: async (ctx, args) => {
    // Patch updates an existing document with shallow merge
    await ctx.db.patch(args.userId, {
      status: args.status,
      lastUpdated: Date.now(),
    });
    return null;
  },
});
```

For more detailed information and additional patterns, refer to the complete reference documentation.

