Skip to content

fix(FR-3017): version-branch myRoles entityType filter shape#7686

Merged
graphite-app[bot] merged 1 commit into
mainfrom
fix/FR-3017-rbac-element-type-filter
Jun 4, 2026
Merged

fix(FR-3017): version-branch myRoles entityType filter shape#7686
graphite-app[bot] merged 1 commit into
mainfrom
fix/FR-3017-rbac-element-type-filter

Conversation

@nowgnuesLee

@nowgnuesLee nowgnuesLee commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Resolves #7665 (FR-3017)

Problem

useCurrentUserProjectRoles issued the myRoles query with permission.entityType always as the RBACElementTypeFilter wrapper ({ equals: PROJECT_ADMIN_PAGE }). Cores <= 26.4.3 define this field as a direct RBACElementType enum and reject the wrapper at query-validation time:

Enum "RBACElementType" cannot represent non-enum value: {equals: PROJECT_ADMIN_PAGE}
(GRAPHQL_VALIDATION_FAILED)

Because it is a query-validation error (not a field error), @catch(to: RESULT) cannot absorb it — the whole query is rejected and the app fails to load against those backends.

Fix (option a — version branch)

  • backend.ai-client: add a rbac-element-type-filter capability flag, gated at 26.4.4rc4 — the exact tag where the backend switched PermissionNestedFilter.{scope,entity}Type to the RBACElementTypeFilter wrapper (backend.ai #11442).
  • useCurrentUserProjectRoles: pass the permission filter as a Relay variable so a single compiled query carries either shape, and build it at runtime:
    • >= 26.4.4rc4 → wrapper { entityType: { equals: PROJECT_ADMIN_PAGE } }
    • <= 26.4.3 / 26.4.4rc1-3 → direct enum { entityType: PROJECT_ADMIN_PAGE }

The generated Relay type only models the latest (wrapper) shape, so the legacy branch is cast (as unknown as ...).

Why gate on the exact rc

26.4.4rcN builds already carry the wrapper, but PEP440 sorts 26.4.4rcN < 26.4.4. Gating at the stable 26.4.4 would misclassify rc4–rc6 as older and send them the direct enum, re-triggering the bug. Gating at 26.4.4rc4 classifies every release correctly:

version branch
<= 26.4.3 direct enum
26.4.4rc1–3 (pre-wrapper) direct enum
26.4.4rc4–rc6, 26.4.4, 26.5.x+ wrapper

Verification

Automated — bash scripts/verify.sh: Lint / Format / TypeScript PASS, Relay regenerated.
(The harness's "Vite warmup paths" check also fails on a clean main — pre-existing, unrelated to this change.)

TODO — manual checks (cannot be covered by verify.sh)

verify.sh only compiles against the latest (wrapper) schema; it cannot exercise the <= 26.4.3 path. Confirm both branches against live backends:

Wrapper path — backend >= 26.4.4rc4:

  • Super-admin loads the app; no GRAPHQL_VALIDATION_FAILED in console/network
  • Regular (non-admin) user loads the app; myRoles resolves
  • Network tab: myRoles request sends permission.entityType = { equals: PROJECT_ADMIN_PAGE }

Direct-enum path — backend <= 26.4.3:

  • Super-admin and regular user both load the app without GRAPHQL_VALIDATION_FAILED
  • Network tab: myRoles request sends permission.entityType = PROJECT_ADMIN_PAGE (bare enum)
  • Project-admin scope still resolves (admin UI gating unchanged)

Regression:

  • No data/schema.graphql divergence required (acceptance criterion from FR-3017)

Note: after pulling this change onto a running dev session, do a full browser refresh_features is cached on the global backendaiclient, so HMR alone may keep the stale capability map.

@github-actions github-actions Bot added the size:L 100~500 LoC label Jun 2, 2026

Copy link
Copy Markdown
Contributor Author

How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • flow:merge-queue - adds this PR to the back of the merge queue
  • flow:hotfix - for urgent changes, fast-track this PR to the front of the merge queue

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has required the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Coverage Report for react-coverage (./react)

Status Category Percentage Covered / Total
🔵 Lines 6.65% 1808 / 27168
🔵 Statements 5.42% 2004 / 36908
🔵 Functions 5.43% 300 / 5521
🔵 Branches 3.78% 1306 / 34463
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
react/src/hooks/useCurrentUserProjectRoles.ts 0% 0% 0% 0% 40-141
Generated in workflow #1352 for commit e708bc3 by the Vitest Coverage Report Action

@nowgnuesLee nowgnuesLee force-pushed the fix/FR-3017-rbac-element-type-filter branch 2 times, most recently from 7c70016 to 1c1f9a1 Compare June 2, 2026 09:03
@nowgnuesLee nowgnuesLee marked this pull request as ready for review June 2, 2026 09:09
@nowgnuesLee nowgnuesLee requested review from agatha197, Copilot and ironAiken2 and removed request for Copilot June 2, 2026 09:09
Comment thread react/src/hooks/useCurrentUserProjectRoles.ts Outdated
@nowgnuesLee nowgnuesLee force-pushed the fix/FR-3017-rbac-element-type-filter branch from 1c1f9a1 to 0946581 Compare June 3, 2026 15:51
Copilot AI review requested due to automatic review settings June 3, 2026 15:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a backwards-compatibility break in the myRoles GraphQL query filter shape across Backend.AI core versions by introducing a capability-gated runtime branch: older cores (<= 26.4.3 / 26.4.4rc1–3) receive a direct enum value, while newer cores (>= 26.4.4rc4) receive the newer { equals: ... } wrapper form.

Changes:

  • Added a new backend.ai-client capability flag (rbac-element-type-filter) gated at manager version 26.4.4rc4.
  • Updated useCurrentUserProjectRoles to pass the permission filter via a Relay variable and construct the correct runtime shape based on capability detection.
  • Regenerated the Relay query artifact to reflect the new query variable.

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated no comments.

File Description
react/src/hooks/useCurrentUserProjectRoles.ts Builds permission.entityType filter shape at runtime (wrapper vs bare enum) and sends it as a Relay variable to avoid query-validation failures on older cores.
react/src/generated/useCurrentUserProjectRolesQuery.graphql.ts Regenerated Relay artifact for the new $permissionFilter variable and non-literal filter argument.
packages/backend.ai-client/src/client.ts Adds rbac-element-type-filter feature flag gated at 26.4.4rc4 to correctly classify rc builds vs stable per PEP440 ordering.
Files not reviewed (1)
  • react/src/generated/useCurrentUserProjectRolesQuery.graphql.ts: Language not supported

@agatha197 agatha197 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@graphite-app

graphite-app Bot commented Jun 4, 2026

Copy link
Copy Markdown

Merge activity

Resolves #7665 (FR-3017)

## Problem

`useCurrentUserProjectRoles` issued the `myRoles` query with `permission.entityType` always as the **`RBACElementTypeFilter` wrapper** (`{ equals: PROJECT_ADMIN_PAGE }`). Cores **<= 26.4.3** define this field as a **direct `RBACElementType` enum** and reject the wrapper at **query-validation** time:

```
Enum "RBACElementType" cannot represent non-enum value: {equals: PROJECT_ADMIN_PAGE}
(GRAPHQL_VALIDATION_FAILED)
```

Because it is a query-validation error (not a field error), `@catch(to: RESULT)` cannot absorb it — the whole query is rejected and the app **fails to load** against those backends.

## Fix (option a — version branch)

- **`backend.ai-client`**: add a `rbac-element-type-filter` capability flag, gated at **`26.4.4rc4`** — the exact tag where the backend switched `PermissionNestedFilter.{scope,entity}Type` to the `RBACElementTypeFilter` wrapper (backend.ai #11442).
- **`useCurrentUserProjectRoles`**: pass the `permission` filter as a **Relay variable** so a single compiled query carries either shape, and build it at runtime:
  - `>= 26.4.4rc4` → wrapper `{ entityType: { equals: PROJECT_ADMIN_PAGE } }`
  - `<= 26.4.3` / `26.4.4rc1-3` → direct enum `{ entityType: PROJECT_ADMIN_PAGE }`

The generated Relay type only models the latest (wrapper) shape, so the legacy branch is cast (`as unknown as ...`).

### Why gate on the exact rc
`26.4.4rcN` builds already carry the wrapper, but PEP440 sorts `26.4.4rcN < 26.4.4`. Gating at the stable `26.4.4` would misclassify rc4–rc6 as older and send them the direct enum, re-triggering the bug. Gating at `26.4.4rc4` classifies every release correctly:

| version | branch |
|---|---|
| <= 26.4.3 | direct enum |
| 26.4.4rc1–3 (pre-wrapper) | direct enum |
| 26.4.4rc4–rc6, 26.4.4, 26.5.x+ | wrapper |

## Verification

Automated — `bash scripts/verify.sh`: **Lint / Format / TypeScript PASS**, Relay regenerated.
(The harness's "Vite warmup paths" check also fails on a clean `main` — pre-existing, unrelated to this change.)

### TODO — manual checks (cannot be covered by verify.sh)

`verify.sh` only compiles against the latest (wrapper) schema; it cannot exercise the `<= 26.4.3` path. Confirm both branches against live backends:

**Wrapper path — backend `>= 26.4.4rc4`:**
- [ ] Super-admin loads the app; no `GRAPHQL_VALIDATION_FAILED` in console/network
- [ ] Regular (non-admin) user loads the app; `myRoles` resolves
- [ ] Network tab: `myRoles` request sends `permission.entityType = { equals: PROJECT_ADMIN_PAGE }`

**Direct-enum path — backend `<= 26.4.3`:**
- [ ] Super-admin and regular user both load the app without `GRAPHQL_VALIDATION_FAILED`
- [ ] Network tab: `myRoles` request sends `permission.entityType = PROJECT_ADMIN_PAGE` (bare enum)
- [ ] Project-admin scope still resolves (admin UI gating unchanged)

**Regression:**
- [ ] No `data/schema.graphql` divergence required (acceptance criterion from FR-3017)

> Note: after pulling this change onto a running dev session, do a **full browser refresh** — `_features` is cached on the global `backendaiclient`, so HMR alone may keep the stale capability map.
@graphite-app graphite-app Bot force-pushed the fix/FR-3017-rbac-element-type-filter branch from 0946581 to e708bc3 Compare June 4, 2026 02:27
@graphite-app graphite-app Bot merged commit e708bc3 into main Jun 4, 2026
14 checks passed
@graphite-app graphite-app Bot deleted the fix/FR-3017-rbac-element-type-filter branch June 4, 2026 02:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100~500 LoC

Projects

None yet

Development

Successfully merging this pull request may close these issues.

myRoles permission filter sends RBACElementType as EnumFilter, breaking 26.4.x backends

3 participants