Auth0 Action Execution Order When Rendering Forms
Last Updated:
Overview
The execution order of Auth0 Actions continues when a Post-Login Action calls the api.prompt.render() method to display a form. Code located after the render call still executes and appears in the Real-time Logs before Auth0 redirects the user to the form. The api.prompt.render() method flags the transaction without halting the script, requiring explicit return statements to prevent subsequent code execution.
Applies To
- Auth0
- Auth0 Actions
- Post-Login Actions
- Auth0 Forms
Solution
How does Auth0 execute code when rendering a form?
The api.prompt.render() method does not stop the Action from running further code. It flags the transaction, but the onExecutePostLogin function keeps executing to completion. Auth0 acts on the flag, pauses the pipeline, and sends the user to the form only after onExecutePostLogin fully resolves. When the user completes the form and reaches the Ending screen node, Auth0 resumes the pipeline by calling onContinuePostLogin on that exact same Action.
Review the Step-by-Step Execution Trace
Review the following example Action to understand the execution flow.
exports.onExecutePostLogin = async (event, api) => {
console.log("Beginning of ExecutePostLogin");
api.prompt.render('ap_MY_FORM_ID');
console.log("Remaining codes in ExecutePostLogin");
};
exports.onContinuePostLogin = async (event, api) => {
console.log("Continue on ContinuePostLogin");
};
Trace the execution of the provided Action code through the following sequential steps:
- The login flow triggers the Action, and the runtime begins executing
onExecutePostLogin. - The
console.log("Beginning of ExecutePostLogin")statement prints to the Real-time Logs. - The Action calls the
api.prompt.render('ap_MY_FORM_ID')method. This call does not return or throw an error. It marks the transaction as needing to render a form once the current Action finishes. - The script proceeds to the next line and logs
"Remaining codes in ExecutePostLogin"because the render call does not interrupt execution. - The
onExecutePostLoginfunction finishes and resolves. Auth0 checks the transaction state, identifies the form render request, pauses the authentication flow, and sends the user to the form. - The user interacts with the form. The form flow completes and routes the browser back to the Auth0 authentication pipeline once the user reaches the Ending screen node.
- Auth0 tracks which Action paused the flow and resumes execution by invoking the
onContinuePostLoginhandler of that exact Action. - The
console.log("Continue on ContinuePostLogin")statement prints to the Real-time Logs.
Why does trailing code still run after the render call?
The API methods, such as api.prompt.render(), api.redirect.sendUserTo(), and api.access.deny(), act as declarative signals rather than control-flow interrupts. These methods set the state on the transaction object instead of halting the JavaScript call stack. Auth0 only inspects the accumulated state after the exported function resolves.
Guard logic explicitly with an early return statement to prevent code from executing when the form renders.
exports.onExecutePostLogin = async (event, api) => {
if (!event.user.user_metadata.company_name) {
api.prompt.render('ap_MY_FORM_ID');
return;
}
doSomethingThatShouldNotRunWhenFormIsShown();
};