API-key GraphQL query spanning array and docker roots crashes Casbin enforcement

Open
#2,060 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
52/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Quiet
Tech stack
graphql, typescript

Research direction

Reproduce the multi-root API-key query, then inspect AuthService.validateApiKeyCasbin(), syncApiKeyPermissions(), and batchProcess() in tag v4.35.1 alongside Casbin coreEnforcer.js around line 422. Compare combined, array-only, and docker-only requests; done means authorized roots return successfully without an INTERNAL_SERVER_ERROR or an unbounded authorization failure.

Written by the indexing model from the issue text.

Description

Environment

  • Unraid OS: 7.3.2
  • Unraid API: 4.35.1+a9625ae2
  • Authentication: API key with read access to both ARRAY and DOCKER resources
  • Transport: local GraphQL endpoint

No hostnames, addresses, API-key values, or registration data are included.

Minimal reproduction

A single request containing one field from each root fails:

query MinimalArrayDocker {
  array { state }
  docker { containers { names } }
}

HTTP 200 response:

{
  "data": null,
  "errors": [
    {
      "message": "Cannot read properties of undefined (reading '0')",
      "path": ["array"],
      "code": "INTERNAL_SERVER_ERROR"
    }
  ]
}

The order of the two root fields does not change the result.

Controls

On the same host and with the same API key:

query ArrayOnly { array { state } }

and

query DockerOnly { docker { containers { names } } }

both succeed when sent as separate HTTP requests. Five consecutive rounds produced:

  • combined request: 5/5 failed at path array
  • array-only request: 5/5 passed
  • docker-only request: 5/5 passed

Broader incremental tests also showed that array alone succeeds and begins failing as soon as any docker child selection is added to the same operation.

Server stack

PM2 application logs identify the failure in Casbin:

TypeError: Cannot read properties of undefined (reading '0')
    at /usr/local/unraid-api/node_modules/casbin/lib/cjs/coreEnforcer.js:422:90
    at Array.forEach (<anonymous>)
    at Enforcer.privateEnforce (.../casbin/lib/cjs/coreEnforcer.js:421:64)

At Casbin 5.38.0, line 422 reads from p.policy[i][j] after policyLen was captured.

Source-level observation / hypothesis

Verified source facts in tag v4.35.1:

  • AuthService.validateApiKeyCasbin() synchronizes API-key roles and permissions during validation.
  • syncApiKeyPermissions() deletes the key's existing permissions and re-adds permission/action pairs through batchProcess().
  • batchProcess() starts all add operations together and waits with Promise.allSettled().

Hypothesis, not yet proved: concurrent policy additions or concurrent permission enforcement leaves/observes an undefined policy row. This would explain why either root succeeds alone while two permission-protected roots in one GraphQL operation reach p.policy[i] === undefined.

Expected behavior

A read-only GraphQL operation spanning two authorized roots should return both roots without an internal authorization-engine error. At minimum, authorization failure should produce a bounded authorization error rather than INTERNAL_SERVER_ERROR and null the complete response.

Known-issue check

As of 2026-08-10, searches of open and closed unraid/api issues for the exact exception, array resolver, Casbin, and multi-root API-key queries did not find a matching report. Release notes and commits after 4.35.1 did not identify this specific failure. The deployed host was not upgraded to test a later API version.

Dominant language
TypeScript
Stars
113
Forks
22
Avg merge
10h 40m
Merged PRs (30d)
13

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from unraid/api

All issues in unraid/api

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.