Pedram
Pedram2mo ago

Type error on internal query

Hey there. Beginner developer here, hoping to get help with the following type error on line 3. I don't understand why TypeScript thinks the return type is self-referential.
handler implicitly has return type any because it does not have a return type annotation and is referenced directly or indirectly in one of its expressions. ts(7023)
// openAi.ts
export const getToken = internalQuery({
handler: async (ctx, _) => await ctx.runQuery(internal.secrets.get, {key: 'openAiKey'})
})

// secrets.ts
export const get = internalQuery({
args: {key: v.string()},
handler: async (ctx, _) => await ctx.db.query('secrets').filter(q => q.eq('key', args.key)).unique()
})
// openAi.ts
export const getToken = internalQuery({
handler: async (ctx, _) => await ctx.runQuery(internal.secrets.get, {key: 'openAiKey'})
})

// secrets.ts
export const get = internalQuery({
args: {key: v.string()},
handler: async (ctx, _) => await ctx.db.query('secrets').filter(q => q.eq('key', args.key)).unique()
})
6 Replies
Convex Bot
Convex Bot2mo 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!
lee
lee2mo ago
calling ctx.runQuery from a query is usually not useful. instead, you can do this https://docs.convex.dev/production/best-practices/#use-helper-functions-to-write-shared-code
Best Practices | Convex Developer Hub
Here's a collection of our recommendations on how best to use Convex to build
lee
lee2mo ago
if you really want to do ctx.runQuery from a query, the error you're hitting is described here https://docs.convex.dev/functions/actions#dealing-with-circular-type-inference
Actions | Convex Developer Hub
Actions can call third party services to do things such as processing a payment
Pedram
PedramOP4w ago
Thank you! Helper functions are what I need to use. I have a follow-up question. What is the best way to call a helper function that needs a QueryCtx from an internalAction? The following doesn't work because secrets.get expects a QueryCtx.
// openAi.ts
export const setTokenIfNotPresent = internalAction({
handler: async (ctx, _) => {
const secret = await secrets.get(ctx, {key: 'openAiKey'})
if (secret === null) // obtain and set new token
})

// secrets.ts
export async function get(ctx: QueryCtx, key: string) {
ctx.db.query('secrets').filter(q => q.eq('key', args.key)).unique()
})
// openAi.ts
export const setTokenIfNotPresent = internalAction({
handler: async (ctx, _) => {
const secret = await secrets.get(ctx, {key: 'openAiKey'})
if (secret === null) // obtain and set new token
})

// secrets.ts
export async function get(ctx: QueryCtx, key: string) {
ctx.db.query('secrets').filter(q => q.eq('key', args.key)).unique()
})
ballingt
ballingt4w ago
Here you do need to write a separate (internal) query, and call that from teh action with const secret = await ctx.runQuery(api.secrets.get, {key})
mikeysee
mikeysee4w ago
Tom beat me to it, but no you cant call them directly from Actions. Checkout the docs on actions here: https://docs.convex.dev/functions/actions As Tom mentioned you can use runQuery to get the data you need. The query could also be an internalQuery if you didnt want to expose that particularly set of data to the client. Another approach I like to do is to simply pass in the data that the action needs via its args. This will "freeze" the data at the time you schedule or call that action however so that may or may not be what you want to do.
Actions | Convex Developer Hub
Actions can call third party services to do things such as processing a payment

Did you find this page helpful?