vini
vini3w ago

Cannot solve "Convex functions should not directly call other Convex functions"

I searched, asked AI and tried to create helper functions but I can't get rid of this warn, it seems to be happening in my Promise.all() because I get a lot of logs. My helper functions:
// convex/models/routes.ts

import { geospatial } from "@/convex";
import { internal } from "@/convex/_generated/api";
import { Id } from "@/convex/_generated/dataModel";
import { ActionCtx, MutationCtx } from "@/convex/_generated/server";
import schema from "@/convex/schema";
import { Infer } from "convex/values";

export async function insertRoute(
ctx: MutationCtx,
data: Infer<typeof schema.tables.routes.validator>,
): Promise<Id<"routes">> {
return await ctx.db.insert("routes", { ...data });
}

export async function insertGeospatialPoint(
ctx: MutationCtx,
routeId: Id<"routes">,
point: {
latitude: number;
longitude: number;
},
) {
return await geospatial.insert(
ctx,
routeId,
{
latitude: point.latitude,
longitude: point.longitude,
},
{},
);
}

// NEW FUNCTION
export async function insertManyGeospatialPoints(
ctx: ActionCtx,
routeId: Id<"routes">,
points: {
latitude: number;
longitude: number;
}[],
) {
const promises = points.map((point) =>
ctx.runMutation(internal.routes.insertGeospatialPointMutation, {
routeId,
point,
}),
);
return await Promise.all(promises);
}
// convex/models/routes.ts

import { geospatial } from "@/convex";
import { internal } from "@/convex/_generated/api";
import { Id } from "@/convex/_generated/dataModel";
import { ActionCtx, MutationCtx } from "@/convex/_generated/server";
import schema from "@/convex/schema";
import { Infer } from "convex/values";

export async function insertRoute(
ctx: MutationCtx,
data: Infer<typeof schema.tables.routes.validator>,
): Promise<Id<"routes">> {
return await ctx.db.insert("routes", { ...data });
}

export async function insertGeospatialPoint(
ctx: MutationCtx,
routeId: Id<"routes">,
point: {
latitude: number;
longitude: number;
},
) {
return await geospatial.insert(
ctx,
routeId,
{
latitude: point.latitude,
longitude: point.longitude,
},
{},
);
}

// NEW FUNCTION
export async function insertManyGeospatialPoints(
ctx: ActionCtx,
routeId: Id<"routes">,
points: {
latitude: number;
longitude: number;
}[],
) {
const promises = points.map((point) =>
ctx.runMutation(internal.routes.insertGeospatialPointMutation, {
routeId,
point,
}),
);
return await Promise.all(promises);
}
Rest of code is in the next comment because of Discord limit.
24 Replies
Convex Bot
Convex Bot3w ago
Thanks for posting in <#1088161997662724167>. Reminder: If you have a Convex Pro account, use the Convex Dashboard to file support tickets. - Provide context: What are you trying to achieve, what is the end-user interaction, what are you seeing? (full error message, command output, etc.) - Use search.convex.dev to search Docs, Stack, and Discord all at once. - Additionally, you can post your questions in the Convex Community's <#1228095053885476985> channel to receive a response from AI. - Avoid tagging staff unless specifically instructed. Thank you!
vini
viniOP3w ago
// convex/routes.ts

import { geospatial } from "@/convex";
import { internal } from "@/convex/_generated/api";
import { Id } from "@/convex/_generated/dataModel";
import { action, internalMutation, query } from "@/convex/_generated/server";
import { coordinateSchema, routeSchema } from "@/convex/schema";
import { v } from "convex/values";
import * as Routes from "./model/routes";

export const insertRouteMutation = internalMutation({
args: {
...routeSchema,
},
handler: async (ctx, data) => Routes.insertRoute(ctx, data),
});

export const insertGeospatialPointMutation = internalMutation({
args: {
routeId: v.id("routes"),
point: coordinateSchema,
},
handler: async (ctx, { routeId, point }) =>
Routes.insertGeospatialPoint(ctx, routeId, point),
});

export const createRouteWithPointsAction = action({
args: {
...routeSchema,
points: v.array(coordinateSchema),
},
handler: async (ctx, { points, ...route }) => {
console.log(points.length);
const routeId: Id<"routes"> = await ctx.runMutation(
internal.routes.insertRouteMutation,
route,
);

// UPDATED LINE
await Routes.insertManyGeospatialPoints(ctx, routeId, points);

return routeId;
},
});
// convex/routes.ts

import { geospatial } from "@/convex";
import { internal } from "@/convex/_generated/api";
import { Id } from "@/convex/_generated/dataModel";
import { action, internalMutation, query } from "@/convex/_generated/server";
import { coordinateSchema, routeSchema } from "@/convex/schema";
import { v } from "convex/values";
import * as Routes from "./model/routes";

export const insertRouteMutation = internalMutation({
args: {
...routeSchema,
},
handler: async (ctx, data) => Routes.insertRoute(ctx, data),
});

export const insertGeospatialPointMutation = internalMutation({
args: {
routeId: v.id("routes"),
point: coordinateSchema,
},
handler: async (ctx, { routeId, point }) =>
Routes.insertGeospatialPoint(ctx, routeId, point),
});

export const createRouteWithPointsAction = action({
args: {
...routeSchema,
points: v.array(coordinateSchema),
},
handler: async (ctx, { points, ...route }) => {
console.log(points.length);
const routeId: Id<"routes"> = await ctx.runMutation(
internal.routes.insertRouteMutation,
route,
);

// UPDATED LINE
await Routes.insertManyGeospatialPoints(ctx, routeId, points);

return routeId;
},
});
lee
lee3w ago
hmm i don't see anything wrong in this code. can you share the code for import { geospatial } from "@/convex"; ?
vini
viniOP3w ago
GitHub
GitHub - get-convex/geospatial: Convex component for geospatial ind...
Convex component for geospatial indexing. Contribute to get-convex/geospatial development by creating an account on GitHub.
lee
lee3w ago
makes sense. and the code is export const geospatial = new GeospatialIndex(...) or something?
vini
viniOP3w ago
yes, here
// convex/index.ts
import { Id } from "@/convex/_generated/dataModel";
import { GeospatialIndex } from "@convex-dev/geospatial";
import { components } from "./_generated/api";

export const geospatial = new GeospatialIndex<Id<"routes">>(
components.geospatial,
);
// convex/index.ts
import { Id } from "@/convex/_generated/dataModel";
import { GeospatialIndex } from "@convex-dev/geospatial";
import { components } from "./_generated/api";

export const geospatial = new GeospatialIndex<Id<"routes">>(
components.geospatial,
);
ballingt
ballingt3w ago
What version of that component are you using?
vini
viniOP3w ago
"@convex-dev/geospatial": "^0.1.7", since it's still in beta, could be a minor issue from the lib?
lee
lee3w ago
could be, but i don't see an issue with the lib though. is this happening in prod or convex-test? oh i see you're calling internal.routes.insertGeospatialPoint but according to your filepaths it would be internal.index.insertGeospatialPoint. can you share the contents of convex/routes.ts?
vini
viniOP3w ago
updated the code to use my helper function but there's no internal.routes, with internal it seems I can access any internalMutation, internalAction or internalQuery
ballingt
ballingt3w ago
You have code that calls internal.routes.insertGeospatialPointMutation, that's a function presumably defined in convex/routes.ts? that's code we can't see and we're wondering if has this pattern in it
vini
viniOP3w ago
my bad, routes is the current file and it's also a table in my db this is routes.ts
ballingt
ballingt3w ago
Did the "Convex functions should not directly call other Convex functions" error have any other details? to make sure we're on the same page, what we're trying to do is fine where a convex query, mutation, or action is being called directly instead of using helper functions so just looking at the code could be enough, if we can find the right code to look at
vini
viniOP3w ago
also, these warns only happens on my local terminal (when running npx convex dev), there are no warns in my project logs
vini
viniOP3w ago
no more details from logs
No description
ballingt
ballingt3w ago
Oh isn't it just this?
await Routes.insertManyGeospatialPoints(ctx, routeId, points);
await Routes.insertManyGeospatialPoints(ctx, routeId, points);
oh that's what Lee asked abotu alreacyx
vini
viniOP3w ago
hmm this is the helper function
ballingt
ballingt3w ago
can you show that code?
vini
viniOP3w ago
am I doing it wrong? here
vini
viniOP3w ago
Best Practices | Convex Developer Hub
This is a list of best practices and common anti-patterns around using Convex.
ballingt
ballingt3w ago
huh yeah it looks ok, it's not a Convex Function, it's a helper
vini
viniOP3w ago
seems like any interaction with geospatial will log this warning, so if you're saying the code looks ok I could just ignore it for now
ballingt
ballingt3w ago
Sounds good Looks like this is the issue https://github.com/get-convex/geospatial/blob/b2dcb6a4c0cdf8ccfc8822a96694a5369d2ff6c7/src/component/document.ts#L49 in the geospatial component thanks for reporting @vini, we'll let you know when there's a new version of the geospatial component that fixes this
vini
viniOP3w ago
thanks for helping and sure I'm looking to further use it so I'll be checking any updates 😁

Did you find this page helpful?