Can actions actually return a value?
The documentation is not very clear about whether actions can have a return value or not. If they can't, I'd apprecaite it if the documentation could acknowledge this clearly. If they can, I'd appreciate a clear example showcasing how to do this.
For example, I would like to have this kind of action.
I am not interested in calling this action in the front-end (hence
I want to actually await the action and get its return value before executing the rest of the backend code (in this case, a mutation), is there a way to do this? I also tried to call
internalAction
). I've seen in the demos on GitHub (https://github.com/get-convex/convex-demos) examples of actions being called in the front-end (https://github.com/get-convex/convex-demos/tree/main/vector-search) to get a return value, but not examples of actions returning something in the backend.
Indeed, my seemingly only option to run an action in the backend is with the scheduler:
The above schedules the action to run in the future, which is not what I want.I want to actually await the action and get its return value before executing the rest of the backend code (in this case, a mutation), is there a way to do this? I also tried to call
openai.beta.threads
, but the linter complains that this expression it's not callable.
Originally I tried to just use a normal function, or what it's equivalent, just call openai.beta.threads.create()
inside of my mutation, but I got this:
Thank you!GitHub
GitHub - get-convex/convex-demos: Demo apps built on Convex.
Demo apps built on Convex. Contribute to get-convex/convex-demos development by creating an account on GitHub.
GitHub
convex-demos/vector-search at main · get-convex/convex-demos
Demo apps built on Convex. Contribute to get-convex/convex-demos development by creating an account on GitHub.
3 Replies
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!
hi! great questions, and not readily answered by docs; we'll work on that.
actions can return values. the values can be JSON-serializable objects or a few other types. notably complex streams and classes can't be returned: https://docs.convex.dev/database/types#convex-values
actions can run most code, including calling openai apis. but there are restrictions on what a
mutation
or query
can call synchronously. because they run as transactions, they cannot have side effects or take a long time (hence no setTimeout
). And mutations can't call actions synchronously, which might take a while or be nondeterministic. https://docs.convex.dev/functions/runtimes#restrictions-on-queries-and-mutations
action return values are only useful when called synchronously, which can happen if called from another action
or an httpAction
or with useAction
from a client. when scheduled with ctx.scheduler.runAfter
or with a cron, the return value isn't useful. Since a mutation can't call an action synchronously, it can't use the action's return value.
so to solve your use-case, i imagine you want to run a mutation that schedules an action, and the action calls ctx.runMutation
at the end, to store its return value and complete the workflow.Runtimes | Convex Developer Hub
Convex functions can run in two runtimes:
Data Types | Convex Developer Hub
All Convex documents are defined as Javascript objects. These objects can have
thanks! that's the flow we arrived at when I discussed it with the support team via email yesterday:
initial mutation:
create the record
schedule the background action
inside the action:
call apis, do anything you want
call a mutation to save the results back to the original record
The app is subscribed to the record via a query, so it automatically updates as you proceed.