Repository navigation
fix(rhai): stop disclosing Rhai internals and router function errors to clients #10004
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
rohan-b99
merged 8 commits into
dev
from
ROUTER-2050-redact-rhai-wrapper-from-client-errors
Oct 8, 2026
Merged
Changes from 1 commit
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
487a337
fix(rhai): redact the Rhai wrapper from client-facing error responses
rohan-b99 e126bda
refactor(rhai): trim redaction comments to the non-obvious points
rohan-b99 40abde7
test(rhai): rename the redacted router-function error test
rohan-b99 762a56c
fix(rhai): hide errors from the router's own Rhai functions from clients
rohan-b99 f08936e
refactor(rhai): trim redaction comments to what the code can't show
rohan-b99 0193084
Merge origin/dev into ROUTER-2050-redact-rhai-wrapper-from-client-errors
rohan-b99 7a25512
fix(rhai): classify a callback error before revealing its text
rohan-b99 b1f507e
docs(rhai): tighten wording of the redacted-error docs and changeset
rohan-b99 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
32 changes: 32 additions & 0 deletions
32
.changesets/fix_rohan_b99_redact_rhai_internals_from_client_errors.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| ### Stop disclosing Rhai internals in client-facing error responses ([PR #10004](https://github.com/apollographql/router/pull/10004)) | ||
|
|
||
| When a Rhai script failed, the router wrapped the failure in its own error text before returning it to the client, which exposed the fact that the router runs Rhai, the names of the script's callbacks, and the line and position where the failure happened: | ||
|
|
||
| ```json | ||
| { | ||
| "errors": [ | ||
| { | ||
| "message": "rhai execution error: 'Runtime error: Invalid request (line 25, position 39)\nin call to function 'process_router_request' @ 'process_router_request' (line 6, position 29)'" | ||
| } | ||
| ] | ||
| } | ||
| ``` | ||
|
|
||
| Clients now receive only the message the script author chose. A thrown string is returned as written, with the Rhai wrapper stripped: | ||
|
|
||
| ```rhai | ||
| throw "Invalid request"; // client sees: Invalid request | ||
| throw #{ status: 403, message: "Forbidden" }; // client sees: Forbidden | ||
| throw #{ status: 403, body: #{ errors: [...] } }; // client sees the custom body | ||
| ``` | ||
|
|
||
| Anything the script did *not* choose is replaced with the status code's reason phrase, and the underlying error is logged at `ERROR` level instead. This covers failures raised by the Rhai engine itself (such as calling an undefined function or a type mismatch), a `throw` carrying only a status - `throw #{ status: 400 }` now reads `Bad Request` rather than dumping the thrown object - failures in the router's own Rhai functions that carry no message, such as reading a header that isn't present, and a `throw` the router cannot read as a message - a value that is not a string or an object map, such as `throw 42`, or a map with an unreadable field, such as `throw #{ status: "four hundred", message: "Invalid request" }`, which is discarded whole so the `message` beside the bad status goes with it. | ||
|
|
||
| Failures in the router's own Rhai functions that *do* carry a message are only partly covered: the wrapper, the script line and position and the chain of callbacks are gone, but the function's own message still reaches the client. `env::get()` on a variable that isn't set still reports `could not expand variable: MY_VAR, environment variable not found`, and `json::decode()` on malformed input still reports the parse error. A router function's error is indistinguishable from a script's own `throw`, so telling them apart would take recording which side raised it - the Rhai customization docs carry this as a documented limitation. If a script of yours calls those functions on a client-facing path, catch the error and throw your own. | ||
|
rohan-b99 marked this conversation as resolved.
Outdated
|
||
|
|
||
| Two things to be aware of when upgrading: | ||
|
|
||
| - Client-facing messages for a thrown string no longer include the `rhai execution error: 'Runtime error: ... (line N, position M)'` wrapper. Only the string you threw is returned. The full error is still in the logs. | ||
| - Nothing changes for scripts themselves: a `catch` block receives exactly what it received before, and status codes are unchanged. | ||
|
|
||
| By [@rohan-b99](https://github.com/rohan-b99) in https://github.com/apollographql/router/pull/10004 | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
...outer__plugins__rhai__tests__it_redacts_a_binding_error_that_carries_no_message@logs.snap
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| --- | ||
| source: apollo-router/src/plugins/rhai/tests.rs | ||
| expression: yaml | ||
| --- | ||
| - fields: {} | ||
| level: ERROR | ||
| message: "map_request callback failed: ErrorDetails {\n status: 500,\n message: Some(\n \"Internal Server Error\",\n ),\n position: Some(\n Position {\n line: Some(\n 15,\n ),\n pos: Some(\n 32,\n ),\n },\n ),\n body: None,\n internal_detail: Some(\n \"rhai execution error: 'Runtime error (line 15, position 32)'\",\n ),\n}" | ||
| span: | ||
| name: rhai_plugin | ||
| otel.kind: INTERNAL | ||
| rhai service: "supergraph :: Request" | ||
| spans: | ||
| - name: rhai_plugin | ||
| otel.kind: INTERNAL | ||
| rhai service: "supergraph :: Request" |
8 changes: 8 additions & 0 deletions
8
...pshots/apollo_router__plugins__rhai__tests__it_redacts_an_empty_response_stream@logs.snap
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| --- | ||
| source: apollo-router/src/plugins/rhai/tests.rs | ||
| expression: yaml | ||
| --- | ||
| - fields: | ||
| rhai.stage: SupergraphResponse | ||
| level: ERROR | ||
| message: "map_response was not called: ErrorDetails {\n status: 500,\n message: Some(\n \"Internal Server Error\",\n ),\n position: None,\n body: None,\n internal_detail: Some(\n \"rhai execution error: the response stream ended before a primary response was available\",\n ),\n}" |
15 changes: 15 additions & 0 deletions
15
...lo_router__plugins__rhai__tests__it_redacts_engine_errors_from_client_responses@logs.snap
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| --- | ||
| source: apollo-router/src/plugins/rhai/tests.rs | ||
| expression: yaml | ||
| --- | ||
| - fields: {} | ||
| level: ERROR | ||
| message: "map_request callback failed: ErrorDetails {\n status: 500,\n message: Some(\n \"Internal Server Error\",\n ),\n position: None,\n body: None,\n internal_detail: Some(\n \"rhai execution error: 'Function not found: this_function_does_not_exist () (line 14, position 5)'\",\n ),\n}" | ||
| span: | ||
| name: rhai_plugin | ||
| otel.kind: INTERNAL | ||
| rhai service: "execution :: Request" | ||
| spans: | ||
| - name: rhai_plugin | ||
| otel.kind: INTERNAL | ||
| rhai service: "execution :: Request" |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.