---
title: "Login Escape Hatch · RUAL Documentation"
description: "Force the built-in login page with ?studio=1 when a custom login page locks you out."
canonical: https://docs.rual.nl/interfaces/login-escape-hatch
language: en
---

# Login Escape Hatch

A custom login page that breaks would normally lock every developer out of the cluster it belongs to. It cannot: any non-empty studio query parameter bypasses user-defined page resolution and forces the built-in login page to render.

### Why the Escape Hatch Exists

[Overwrite Default Pages](https://docs.rual.nl/interfaces/overwrite-default-pages) explains how a [State Page](https://docs.rual.nl/block-types/state%20ui/state_page) whose event URL is `login` replaces the built-in login screen. That override is deliberate and it is complete: when the cluster resolves an incoming request it looks for a blueprint page claiming the path *before* it considers its own built-in pages. A page you define at `/login` therefore shadows the core login screen entirely.

Which is exactly what you want, right up to the moment that page stops working. A blank render, a flow error, a half-finished edit, a blueprint someone deactivated: and the one URL every developer needs to sign in is the one URL that no longer works. Without a way around it, fixing the page would require signing in, and signing in would require the page.

The escape hatch cuts that loop. Any request carrying a non-empty `studio` query parameter skips user-defined page resolution completely and renders the cluster's own page instead. The guarantee it buys is simple: the studio stays reachable even when an entity has broken its custom page.

### Using It

Append `?studio=1` to the URL of the page you need. The built-in version renders, regardless of what any blueprint has claimed for that path.

| URL | Renders |
| --- | --- |
| `https://clienthub.centercom.nl/login?studio=1` | The built-in login screen, even when a custom `/login` page exists. |
| `https://clienthub.centercom.nl/passwordreset?studio=1` | The built-in password reset page. |
| `https://clienthub.centercom.nl/security?studio=1` | The built-in security page for sessions and multi-factor settings. |

If the URL already carries query parameters, add this one alongside them: `/login?redirect=/dashboard&studio=1`.

### The Value Does Not Matter

The cluster never inspects what you pass. It checks only that the parameter is present and non-empty, so `?studio=1`, `?studio=request` and `?studio=please` all behave identically. Elsewhere in this documentation you will see `?studio=request`; that is convention, not a required value.

Two forms do *not* trigger the escape hatch, because both read as an empty value: `?studio=` with nothing after the equals sign, and `?studio` with no equals sign at all. Page resolution then proceeds normally and your custom page still wins. If in doubt, pass a real value.

### Where It Sits in Page Resolution

Every page request is resolved in a fixed order, and the escape hatch owes its reliability to its position in that order:

- **Direct GUID access.** A path starting with `no-uris/` renders that specific page action, used for pages that have no event URL of their own.

- **The studio escape hatch.** A non-empty `studio` parameter skips resolution: no blueprint page is looked up at all.

- **User-defined pages.** Otherwise the path is resolved against the event URLs of your blueprint pages, and a match wins.

- **Built-in pages.** Only when nothing above claimed the request do `login`, `passwordreset` and `security` render from the cluster itself.

Because step 2 sits above step 3, the escape hatch never depends on your custom page being loadable, valid, or active. It is not a fallback that runs after a failed render: with the parameter present, the custom page is never consulted at all. A page that crashes, a page mid-edit, a page whose blueprint is deactivated, and a page that does not exist are all the same case here.

The path is matched after any optional entity prefix is stripped, and on the trailing segment, so `/login`, `/1/login` and `/anything/login` all reach the built-in login screen.

### Recovering From a Broken Login Page

- Open `https://your-cluster/login?studio=1`. The built-in login screen renders.

- Sign in with your normal credentials. The escape hatch decides which page you get and nothing else; authentication is unchanged.

- Open [RUAL Studio](https://docs.rual.nl/interfaces/rual-studio) and find the blueprint holding the State Page whose event URL is `login`. **View Pages** under User Interfaces lists every state page on the cluster, which is the quickest way to find which blueprint claimed the path.

- Fix the flow, or hand the path back to the cluster while you work: deactivate the blueprint, or clear the event URL on the State Page.

- [Deploy](https://docs.rual.nl/deployment/how-to-deploy). Until you do, production keeps serving the previously deployed version of the page.

Because the parameter only ever affects the request that carries it, you can keep working against `?studio=1` for as long as the repair takes, without changing what your users see.

### What It Does Not Do

- **It is not an authentication bypass.** The built-in login page is still a login page: valid credentials are required, and the standard protections continue to apply, including blocking repeated failed attempts against one account and mass authentication attempts from a single IP address.

- **It does not disable your custom page.** Only the request carrying the parameter is affected. Every other visitor keeps reaching the custom page, working or broken, until you fix or deactivate it.

- **It is not a general page bypass.** On paths other than `login`, `passwordreset` and `security` the parameter still skips resolution, but there is no built-in page behind it: signed-out visitors get the built-in login screen, signed-in visitors get a 404.

### Behaviour Across Core Versions

The Go core reproduces the Node behaviour deliberately: Node performs the same default fallback whenever the studio query parameter is present. The recovery URL therefore works identically on a Node cluster and a Go cluster, which matters precisely because you reach for it when something else has already gone wrong.

### Where to Go Next

- [Overwrite Default Pages](https://docs.rual.nl/interfaces/overwrite-default-pages): how to replace the login, password reset and security pages in the first place.

- [Building a Login Page](https://docs.rual.nl/tutorials/login-page): building the custom login page this escape hatch protects you from.

- [Building User Authentication](https://docs.rual.nl/tutorials/user-authentication): a full custom login flow with tokens, 2FA and scope checks.

- [Getting Access](https://docs.rual.nl/cluster/getting-access): receiving credentials and your first sign-in to a cluster.

- [Common Issues](https://docs.rual.nl/troubleshooting/common-issues): other ways a cluster can appear unreachable and what to check first.
