Skip to content

000-fundamentals/000-database_crud confusion #18

@mikecann

Description

@mikecann

I have been running this eval a few times and it errors sometimes and passes sometimes so I dug into it a bit and I can see why as its a little confusing to me too.

It is failing when generating the patchLocation function the prompt for which says:

4. Create a mutation `patchLocation` that:
   - Takes an ID and optional location fields (name, latitude, longitude)
   - Updates only the provided fields
   - Returns null

A failed generation looks like this:

/**
 * Partially update a location's fields.
 */
export const patchLocation = mutation({
  args: {
    id: v.id("locations"),
    name: v.optional(v.string()),
    latitude: v.optional(v.number()),
    longitude: v.optional(v.number()),
  },
  returns: v.null(),
  handler: async (ctx, args) => {
    const { id, ...patchData } = args;
    const existing = await ctx.db.get(id);
    if (!existing) {
      throw new Error(`Location with ID ${id} not found`);
    }
    
    // Only include fields that were provided
    const updates: Record = {};
    if (patchData.name !== undefined) updates.name = patchData.name;
    if (patchData.latitude !== undefined) updates.latitude = patchData.latitude;
    if (patchData.longitude !== undefined) updates.longitude = patchData.longitude;

    await ctx.db.patch(id, updates);
    return null;
  },
});

The error is a TS compile error on the line const updates: Record = {}; Record needs two types.

This error is not actually the problem that I want to talk about with this issue however, this is a simple TS error, but it may well be happening because the model is confused by what it needs to do to satisfy this prompt.

Lets look at what its supposed to generate..

The "answer" output looks like this:

export const patchLocation = mutation({
  args: {
    id: v.id("locations"),
    name: v.optional(v.string()),
    latitude: v.optional(v.number()),
    longitude: v.optional(v.number()),
  },
  returns: v.null(),
  handler: async (ctx, args) => {
    await ctx.db.patch(args.id, {
      name: args.name,
      latitude: args.latitude,
      longitude: args.longitude,
    });
  },
});

The problem is that the convex docs say this for patch:

The db.patch method will patch an existing document, shallow merging it with the given partial document. New fields are added. Existing fields are overwritten. Fields set to undefined are removed.

So because the prompt says "Updates only the provided fields" then the LLM is trying to defensively check to see if the optional args are undefined or not and thus not patch those which would remove those fields if they are set to undefined.

The problem is the answer doesnt do this.

So I think there is a bit of an issue here, im not sure if the prompt should change or the answer should change or we should have some new guideline in here?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions