Skip to content

fix(server): make is_composite_global_id reject non-base64 input gracefully#12943

Open
GopalGB wants to merge 1 commit intoArize-ai:mainfrom
GopalGB:gb-fix/node-route-name-base64-error
Open

fix(server): make is_composite_global_id reject non-base64 input gracefully#12943
GopalGB wants to merge 1 commit intoArize-ai:mainfrom
GopalGB:gb-fix/node-route-name-base64-error

Conversation

@GopalGB
Copy link
Copy Markdown

@GopalGB GopalGB commented Apr 30, 2026

Repro

Phoenix 14.15.0. Navigate to http://localhost:6006/projects/default/traces
(or any /projects/<name>/* route using the project NAME instead of the
base64 global id):

Error fetching GraphQL query 'projectLoaderQuery' with variables {"id":"default"}: an unexpected error occurred

Server-side stack trace:

File "/phoenix/.venv/lib/python3.13/site-packages/phoenix/server/api/queries.py", line 1013, in node
    if is_composite_global_id(id):
File "/phoenix/.venv/lib/python3.13/site-packages/phoenix/server/api/types/node.py", line 10, in is_composite_global_id
    decoded_node_id = b64decode(node_id).decode()
binascii.Error: Incorrect padding

Standalone reproducer (main HEAD):

>>> from phoenix.server.api.types.node import is_composite_global_id
>>> is_composite_global_id("default")
binascii.Error: Incorrect padding

Fix

is_composite_global_id calls b64decode directly without checking
whether the string is valid base64. "default" contains an invalid char
(u) for the standard base64 alphabet AND wrong padding length, so the
exception bubbles up as a generic GraphQL error.

  • is_composite_global_id now uses b64decode(node_id, validate=True)
    inside a try / except (binascii.Error, UnicodeDecodeError, ValueError)
    block and returns False for any input that is not valid base64 or
    whose decoded bytes are not valid UTF-8. Non-base64 strings are by
    definition not composite global ids.
  • Query.node now wraps GlobalID.from_id(id) in a try / except and
    raises a friendly NotFound(f"Unknown node: {id}") instead of leaking
    a GlobalIDValueError-shaped padding error to the client.

Diff:

src/phoenix/server/api/queries.py        | 10 +++++-
src/phoenix/server/api/types/node.py     | 13 +++++++-
tests/unit/server/api/types/test_node.py | 54 ++++++++++++++++++++++++++++-
3 files changed, 74 insertions(+), 3 deletions(-)

Test

5 new test cases in tests/unit/server/api/types/test_node.py:

  • test_is_composite_global_id_returns_false_for_non_base64_input --
    the exact "default" regression.
  • test_is_composite_global_id_handles_invalid_base64 -- parametrized
    over "default", "my-project-name", "abc", "", "===",
    "not!base64".
  • test_is_composite_global_id_returns_false_for_simple_global_id --
    b64encode(b"Project:1") is not composite (single :).
  • test_is_composite_global_id_returns_true_for_composite_id --
    b64encode(b"ExperimentRepeatedRunGroup:1:2") IS composite.
  • test_is_composite_global_id_handles_non_utf8_decoded_bytes --
    random base64 that decodes to non-UTF-8 must not raise.

Verified locally that the fix function returns False for every input
in the parametrized set; verified the bug reproduces on the unmodified
main branch (the standalone reproducer above raises
binascii.Error: Incorrect padding).

Closes #12908

@GopalGB GopalGB requested a review from a team as a code owner April 30, 2026 04:21
@github-project-automation github-project-automation Bot moved this to 📘 Todo in phoenix Apr 30, 2026
@dosubot dosubot Bot added the size:S This PR changes 10-29 lines, ignoring generated files. label Apr 30, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 30, 2026

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@GopalGB GopalGB force-pushed the gb-fix/node-route-name-base64-error branch from 0b4fc05 to e1408cb Compare May 7, 2026 14:35
@GopalGB
Copy link
Copy Markdown
Author

GopalGB commented May 7, 2026

Force-pushed after re-authoring the commit under GopalGB <67310594+GopalGB@users.noreply.github.com> (the previous commit was authored under gopalbagaswar7@gmail.com — a different account — which prevented CLAAssistant from linking to my GopalGB signature).

I have read the CLA Document and I hereby sign the CLA

@GopalGB
Copy link
Copy Markdown
Author

GopalGB commented May 7, 2026

recheck

I have read the CLA Document and I hereby sign the CLA

…acefully

Navigating to `/projects/<name>/*` URLs (e.g. `/projects/default/traces`)
fired a `node` GraphQL query with the literal project NAME as the id.
`is_composite_global_id("default")` then called `b64decode("default")`
directly, which raised `binascii.Error: Incorrect padding` and bubbled
up as a generic "Something went wrong" error in the UI.

Reproducer (against `main`):

```python
>>> from phoenix.server.api.types.node import is_composite_global_id
>>> is_composite_global_id("default")
binascii.Error: Incorrect padding
```

Fix:

* `is_composite_global_id` now uses `b64decode(node_id, validate=True)`
  inside a `try / except (binascii.Error, UnicodeDecodeError, ValueError)`
  block and returns `False` for any input that is not valid base64 or
  whose decoded bytes are not valid UTF-8.  Non-base64 strings are by
  definition not composite global ids.
* `Query.node` now wraps `GlobalID.from_id(id)` in a `try / except` and
  raises a friendly `NotFound(f"Unknown node: {id}")` instead of leaking
  a `GlobalIDValueError`-shaped padding error to the client.

Adds 5 new test cases in `tests/unit/server/api/types/test_node.py`:
  - `test_is_composite_global_id_returns_false_for_non_base64_input`
  - `test_is_composite_global_id_handles_invalid_base64` (parametrized
    over "default", "my-project-name", "abc", "", "===", "not!base64")
  - `test_is_composite_global_id_returns_false_for_simple_global_id`
  - `test_is_composite_global_id_returns_true_for_composite_id`
  - `test_is_composite_global_id_handles_non_utf8_decoded_bytes`

Closes Arize-ai#12908

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: GopalGB <67310594+GopalGB@users.noreply.github.com>
@GopalGB GopalGB force-pushed the gb-fix/node-route-name-base64-error branch from e1408cb to c4b689a Compare May 7, 2026 14:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S This PR changes 10-29 lines, ignoring generated files.

Projects

Status: 📘 Todo

Development

Successfully merging this pull request may close these issues.

UI: /projects/<name>/* routes throw GraphQL error — base64 decode of literal name fails

1 participant