Bug after change function
I made a change on my schema, the table before called profile now is called profiles, I change all names on my code, is reflecting on the backend panel at the convex dashboard, but I'm getting this error:
And I call this function here:
- error Error: Could not find public function for 'profile:update'. Did you forget to run `npx convex dev` or `npx convex deploy`?
at ConvexHttpClient.mutation (webpack-internal:///(rsc)/./node_modules/.pnpm/convex@1.0.2_@clerk+clerk-react@4.23.1_react-dom@18.2.0_react@18.2.0/node_modules/convex/dist/esm/browser/http_client.js:126:23)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async handleClerkWebhook (webpack-internal:///(rsc)/./src/app/(api)/api/webhook/auth/utils.ts:35:17)
at async eval (webpack-internal:///(rsc)/./node_modules/.pnpm/next@13.4.12_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/future/route-modules/app-route/module.js:253:37)
- error Error: Could not find public function for 'profile:update'. Did you forget to run `npx convex dev` or `npx convex deploy`?
at ConvexHttpClient.mutation (webpack-internal:///(rsc)/./node_modules/.pnpm/convex@1.0.2_@clerk+clerk-react@4.23.1_react-dom@18.2.0_react@18.2.0/node_modules/convex/dist/esm/browser/http_client.js:126:23)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async handleClerkWebhook (webpack-internal:///(rsc)/./src/app/(api)/api/webhook/auth/utils.ts:35:17)
at async eval (webpack-internal:///(rsc)/./node_modules/.pnpm/next@13.4.12_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/future/route-modules/app-route/module.js:253:37)
if (body.type === "user.updated") {
const name =
(body.data.first_name ? body.data.first_name : "No") +
" " +
(body.data.last_name ? body.data.last_name : "Name")
console.log(name)
await client.mutation(api.profiles.update, {
userId: body.data.id,
name,
email: body.data.email_addresses[0].email_address,
avatarUrl: body.data.profile_image_url,
})
console.log("Profile updated")
}
if (body.type === "user.updated") {
const name =
(body.data.first_name ? body.data.first_name : "No") +
" " +
(body.data.last_name ? body.data.last_name : "Name")
console.log(name)
await client.mutation(api.profiles.update, {
userId: body.data.id,
name,
email: body.data.email_addresses[0].email_address,
avatarUrl: body.data.profile_image_url,
})
console.log("Profile updated")
}
12 Replies
Functions aren't given names based on tables, they're named based on the filename where they are exported.
So what matters here is the name of the file where you wrote update function. What is that filename?
profiles.ts
i think this is kinda a cache...
How are you running
npx convex dev
, is that showing an error?no, the dev is working fine, the error happens when I make a query for update the profile
Could you share the code for that function, and the full file path of profiles.ts?
yes
just sec
route.ts
profiles.ts
SORRY!
:=)
FOUND THE ERROR..
Sorrry ... miss file, I had 2 routes for webhook,
WORK SMOOTH NOW
import { NextResponse } from "next/server"
import type { WebhookEvent } from "@clerk/clerk-sdk-node"
import { ConvexHttpClient } from "convex/browser"
import { api } from "@convex/_generated/api"
const client = new ConvexHttpClient(process.env.CONVEX_URL!)
export async function POST(req: Request) {
const body = (await req.json()) as WebhookEvent
console.log(body)
try {
if (body.type === "user.created") {
const name =
(body.data.first_name ? body.data.first_name : "No") +
" " +
(body.data.last_name ? body.data.last_name : "Name")
const user = await client.query(api.profiles.getByUserId, { userId: body.data.id })
if (!user) {
await client.mutation(api.profiles.create, {
userId: body.data.id,
name,
email: body.data.email_addresses[0].email_address,
avatarUrl: body.data.profile_image_url,
})
console.log("Profile created")
}
}
if (body.type === "user.updated") {
const name =
(body.data.first_name ? body.data.first_name : "No") +
" " +
(body.data.last_name ? body.data.last_name : "Name")
console.log(name)
await client.mutation(api.profiles.update, {
userId: body.data.id,
name,
email: body.data.email_addresses[0].email_address,
avatarUrl: body.data.profile_image_url,
})
console.log("Profile updated")
}
if (body.type === "user.deleted") {
const user = await client.query(api.profiles.getByUserId, {
userId: body.data.id as string,
})
if (user) {
await client.mutation(api.profiles.remove, { userId: body.data.id as string })
} else {
console.log("Profile deleted not found profiles")
}
}
if (body.type === "session.created") {
// Check if session user_id already has a profiles, if not create one
const user = await client.query(api.profiles.getByUserId, {
userId: body.data.user_id,
})
console.log(user)
if (!user) {
console.log("data", body.data, "\n body.object", body.object)
console.log("Profile not found")
}
}
return NextResponse.json({ status: "ok" })
} catch (e) {
console.log(e)
return NextResponse.json({ status: "error" })
}
}
import { NextResponse } from "next/server"
import type { WebhookEvent } from "@clerk/clerk-sdk-node"
import { ConvexHttpClient } from "convex/browser"
import { api } from "@convex/_generated/api"
const client = new ConvexHttpClient(process.env.CONVEX_URL!)
export async function POST(req: Request) {
const body = (await req.json()) as WebhookEvent
console.log(body)
try {
if (body.type === "user.created") {
const name =
(body.data.first_name ? body.data.first_name : "No") +
" " +
(body.data.last_name ? body.data.last_name : "Name")
const user = await client.query(api.profiles.getByUserId, { userId: body.data.id })
if (!user) {
await client.mutation(api.profiles.create, {
userId: body.data.id,
name,
email: body.data.email_addresses[0].email_address,
avatarUrl: body.data.profile_image_url,
})
console.log("Profile created")
}
}
if (body.type === "user.updated") {
const name =
(body.data.first_name ? body.data.first_name : "No") +
" " +
(body.data.last_name ? body.data.last_name : "Name")
console.log(name)
await client.mutation(api.profiles.update, {
userId: body.data.id,
name,
email: body.data.email_addresses[0].email_address,
avatarUrl: body.data.profile_image_url,
})
console.log("Profile updated")
}
if (body.type === "user.deleted") {
const user = await client.query(api.profiles.getByUserId, {
userId: body.data.id as string,
})
if (user) {
await client.mutation(api.profiles.remove, { userId: body.data.id as string })
} else {
console.log("Profile deleted not found profiles")
}
}
if (body.type === "session.created") {
// Check if session user_id already has a profiles, if not create one
const user = await client.query(api.profiles.getByUserId, {
userId: body.data.user_id,
})
console.log(user)
if (!user) {
console.log("data", body.data, "\n body.object", body.object)
console.log("Profile not found")
}
}
return NextResponse.json({ status: "ok" })
} catch (e) {
console.log(e)
return NextResponse.json({ status: "error" })
}
}
import { query, mutation } from "./_generated/server"
import { v } from "convex/values"
export const getAll = query({
args: {},
handler: async (ctx) => {
return await ctx.db.query("profiles").collect()
},
})
export const getByUserId = query({
args: {
userId: v.string(),
},
handler: async (ctx, { userId }) => {
return await ctx.db
.query("profiles")
.withIndex("byUserId", (q) => q.eq("userId", userId))
.first()
},
})
export const create = mutation({
args: {
userId: v.string(),
name: v.string(),
email: v.string(),
avatarUrl: v.optional(v.string()),
},
handler: async (ctx, { userId, name, email, avatarUrl }) => {
return await ctx.db.insert("profiles", {
userId,
name,
email,
avatarUrl,
})
},
})
export const update = mutation({
args: {
userId: v.string(),
name: v.string(),
email: v.string(),
avatarUrl: v.optional(v.string()),
},
handler: async (ctx, { userId, name, email, avatarUrl }) => {
const profiles = await ctx.db
.query("profiles")
.withIndex("byUserId", (q) => q.eq("userId", userId))
.first()
if (!profiles) {
return await ctx.db.insert("profiles", {
userId,
name,
email,
avatarUrl,
})
}
return await ctx.db.patch(profiles._id, {
userId,
name,
email,
avatarUrl,
})
},
})
export const remove = mutation({
args: {
userId: v.string(),
},
handler: async (ctx, { userId }) => {
const profiles = await ctx.db
.query("profiles")
.withIndex("byUserId", (q) => q.eq("userId", userId))
.first()
if (!profiles) {
return
}
return await ctx.db.delete(profiles._id)
},
})
import { query, mutation } from "./_generated/server"
import { v } from "convex/values"
export const getAll = query({
args: {},
handler: async (ctx) => {
return await ctx.db.query("profiles").collect()
},
})
export const getByUserId = query({
args: {
userId: v.string(),
},
handler: async (ctx, { userId }) => {
return await ctx.db
.query("profiles")
.withIndex("byUserId", (q) => q.eq("userId", userId))
.first()
},
})
export const create = mutation({
args: {
userId: v.string(),
name: v.string(),
email: v.string(),
avatarUrl: v.optional(v.string()),
},
handler: async (ctx, { userId, name, email, avatarUrl }) => {
return await ctx.db.insert("profiles", {
userId,
name,
email,
avatarUrl,
})
},
})
export const update = mutation({
args: {
userId: v.string(),
name: v.string(),
email: v.string(),
avatarUrl: v.optional(v.string()),
},
handler: async (ctx, { userId, name, email, avatarUrl }) => {
const profiles = await ctx.db
.query("profiles")
.withIndex("byUserId", (q) => q.eq("userId", userId))
.first()
if (!profiles) {
return await ctx.db.insert("profiles", {
userId,
name,
email,
avatarUrl,
})
}
return await ctx.db.patch(profiles._id, {
userId,
name,
email,
avatarUrl,
})
},
})
export const remove = mutation({
args: {
userId: v.string(),
},
handler: async (ctx, { userId }) => {
const profiles = await ctx.db
.query("profiles")
.withIndex("byUserId", (q) => q.eq("userId", userId))
.first()
if (!profiles) {
return
}
return await ctx.db.delete(profiles._id)
},
})
No problem, it's good to hear where mistakes often happen. Glad it's working!