Mathias
Mathias•8mo ago

How to fix Uncaught Error: Not found

I have this getTeams query:
export const getTeams = query({
handler: async (ctx) => {
const identity = await ctx.auth.getUserIdentity()

if (!identity) {
throw new Error("Unauthenticated")
}

const userId = identity.subject

const user = await ctx.db
.query("users")
.withIndex("by_user", (q) => q.eq("userId", userId))
.first()

if (!user) {
throw new Error("Not found")
}

const teamIds = await ctx.db
.query("teamMembers")
.withIndex("by_user", (q) => q.eq("userId", user._id))
.collect()

const teams = await Promise.all(
teamIds.map((id) => ctx.db.get(id.teamId as Id<"teams">))
)

return teams.filter((team) => team !== null)
},
})
export const getTeams = query({
handler: async (ctx) => {
const identity = await ctx.auth.getUserIdentity()

if (!identity) {
throw new Error("Unauthenticated")
}

const userId = identity.subject

const user = await ctx.db
.query("users")
.withIndex("by_user", (q) => q.eq("userId", userId))
.first()

if (!user) {
throw new Error("Not found")
}

const teamIds = await ctx.db
.query("teamMembers")
.withIndex("by_user", (q) => q.eq("userId", user._id))
.collect()

const teams = await Promise.all(
teamIds.map((id) => ctx.db.get(id.teamId as Id<"teams">))
)

return teams.filter((team) => team !== null)
},
})
I receive this error when no teams can be found where the user is also a member.
Error: [CONVEX Q(teams:getTeams)] [Request ID: 30092d87adbe25b8] Server Error
Uncaught Error: Not found
at handler (../convex/teams.ts:70:4)

Called by client
Error: [CONVEX Q(teams:getTeams)] [Request ID: 30092d87adbe25b8] Server Error
Uncaught Error: Not found
at handler (../convex/teams.ts:70:4)

Called by client
How can I solve this?
5 Replies
Michal Srb
Michal Srb•8mo ago
You're writing the current user to the database, either via useEffect or a webhook. You need to block the client from subscribing to the query (or let the query return while the user isn't in the DB yet). The former is described here: useEffect: https://docs.convex.dev/auth/database-auth#calling-the-store-user-mutation-from-react webhooks: https://docs.convex.dev/auth/database-auth#waiting-for-current-user-to-be-stored
Storing Users in the Convex Database | Convex Developer Hub
You might want to store user information directly in your Convex database, for
Michal Srb
Michal Srb•8mo ago
The latter (returning while the user hasn't been returned yet) is shown here: https://github.com/Nutlope/notesGPT/blob/main/convex/notes.ts#L45 client can do
const result = useQuery(api.foo.bar);
// null and undefined treated together
if (result == null) {
return "Still loading..."
}
// render the result
const result = useQuery(api.foo.bar);
// null and undefined treated together
if (result == null) {
return "Still loading..."
}
// render the result
GitHub
notesGPT/convex/notes.ts at main · Nutlope/notesGPT
Record voice notes & transcribe, summarize, and get tasks - Nutlope/notesGPT
Mathias
MathiasOP•8mo ago
Thank you for going through this @Michal Srb . I'm already storing the user in the database, but not explicitly how the documentation describes it. I have a create user mutation that I use if the getUser doesn't return any one.
export const getUser = query({
handler: async (ctx) => {
const identity = await ctx.auth.getUserIdentity()

if (!identity) {
throw new Error("Not authenticated")
}

const userId = identity.subject

const user = ctx.db
.query("users")
.withIndex("by_user", (q) => q.eq("userId", userId))
.first()

return user
},
})
export const getUser = query({
handler: async (ctx) => {
const identity = await ctx.auth.getUserIdentity()

if (!identity) {
throw new Error("Not authenticated")
}

const userId = identity.subject

const user = ctx.db
.query("users")
.withIndex("by_user", (q) => q.eq("userId", userId))
.first()

return user
},
})
This is my application layout where it goes wrong with the teams getTeams query:
export default function ApplicationLayout({
children,
}: {
children: React.ReactNode
}) {
const pathname = usePathname()
const user = useStableQueryOverMounts(`user`, api.users.getUser)
const teams = useStableQueryOverMounts("teams", api.teams.getTeams)

const setActiveTeam = useMutation(api.users.setActiveTeam)

const { setOpen } = useCreateTeamOpen()

if (user === null) {
return <CreateUser />
}

// Implement permissions
const permissions: any = []

const activeTeam = teams?.find((team) => team?._id === user?.activeTeam)

return (<>some</>)
}
export default function ApplicationLayout({
children,
}: {
children: React.ReactNode
}) {
const pathname = usePathname()
const user = useStableQueryOverMounts(`user`, api.users.getUser)
const teams = useStableQueryOverMounts("teams", api.teams.getTeams)

const setActiveTeam = useMutation(api.users.setActiveTeam)

const { setOpen } = useCreateTeamOpen()

if (user === null) {
return <CreateUser />
}

// Implement permissions
const permissions: any = []

const activeTeam = teams?.find((team) => team?._id === user?.activeTeam)

return (<>some</>)
}
Not sure what I'm doing wrong with getTeams, as of queries works just fine.
Michal Srb
Michal Srb•8mo ago
You are not blocking this query from executing before the client is authenticated or the user is created.
Mathias
MathiasOP•8mo ago
I ended up doing it in the client. I added the convex-helpers and listened to isPending. Thanks for the help 🙂

Did you find this page helpful?