JTI claim value is not getting regenerated if API calls fails due to rate limit

Open
#1,314 6 comments 0 reactions 5 assignees View on GitHub

@mwwoda is already working on this.

Since Dec 18, 2025.

Assessment

This issue has not been assessed yet.

Description

bug enhancement

This is the same problem fixed in box-node-sdk: https://github.com/box/box-node-sdk/issues/403

See below the 429 followed by the 400. I assume we shouldn't have to handle this with our own retry logic?

DEBUG urllib3.connectionpool:connectionpool.py:475 https://api.box.com:443 "POST /oauth2/token HTTP/1.1" 429 None
DEBUG urllib3.connectionpool:connectionpool.py:475 https://api.box.com:443 "POST /oauth2/token HTTP/1.1" 400 None
ERROR ta_portal.utils.box:box.py:51 Error connecting to Box
Traceback (most recent call last):
File "/app/ta_portal/utils/box.py", line 46, in _get_box_client
me = client.users.get_user_me()
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/python/.local/lib/python3.11/site-packages/box_sdk_gen/managers/users.py", line 396, in get_user_me
response: FetchResponse = self.network_session.network_client.fetch(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/python/.local/lib/python3.11/site-packages/box_sdk_gen/networking/box_network_client.py", line 84, in fetch
request: APIRequest = self._prepare_request(
^^^^^^^^^^^^^^^^^^^^^^
File "/home/python/.local/lib/python3.11/site-packages/box_sdk_gen/networking/box_network_client.py", line 154, in _prepare_request
headers = self._prepare_headers(options, reauthenticate)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/python/.local/lib/python3.11/site-packages/box_sdk_gen/networking/box_network_client.py", line 201, in _prepare_headers
headers['Authorization'] = options.auth.retrieve_authorization_header(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/python/.local/lib/python3.11/site-packages/box_sdk_gen/box/jwt_auth.py", line 337, in retrieve_authorization_header
token: AccessToken = self.retrieve_token(network_session=network_session)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/python/.local/lib/python3.11/site-packages/box_sdk_gen/box/jwt_auth.py", line 330, in retrieve_token
new_token: AccessToken = self.refresh_token(network_session=network_session)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/python/.local/lib/python3.11/site-packages/box_sdk_gen/box/jwt_auth.py", line 311, in refresh_token
token: AccessToken = auth_manager.request_access_token(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/python/.local/lib/python3.11/site-packages/box_sdk_gen/managers/authorization.py", line 327, in request_access_token
response: FetchResponse = self.network_session.network_client.fetch(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/python/.local/lib/python3.11/site-packages/box_sdk_gen/networking/box_network_client.py", line 134, in fetch
self._raise_on_unsuccessful_request(
File "/home/python/.local/lib/python3.11/site-packages/box_sdk_gen/networking/box_network_client.py", line 267, in _raise_on_unsuccessful_request
raise BoxAPIError(
box_sdk_gen.box.errors.BoxAPIError:
Timestamp: 2025-12-18 19:59:15.998280
Underlying error: None
Message: 400 ; Request ID:
Request:
Method: POST
URL: https://api.box.com/oauth2/token
Query params:
{}
Headers:
{ 'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent': 'box-python-generated-sdk-1.14.0',
'X-Box-UA': 'agent=box-python-generated-sdk/1.14.0; env=python/3.11.14'}
Body:
Response:
Status code: 400
Headers:
{ 'Alt-Svc': 'h3=":443"; ma=2592000,h3-29=":443"; ma=2592000',
'Transfer-Encoding': 'chunked',
'box-request-id': '0f16fde51b0146cd4b8dc61a0dc8b06a2',
'cache-control': 'no-store',
'content-type': 'application/json',
'date': 'Thu, 18 Dec 2025 19:59:15 GMT',
'set-cookie': 'box_visitor_id=69445d11ca18b5.90104418; expires=Fri, 18 '
'Dec 2026 19:59:15 GMT; Max-Age=31536000; path=/; '
'domain=.box.com; secure; SameSite=None, bv=EE-28314; '
'expires=Thu, 25 Dec 2025 19:59:15 GMT; Max-Age=604800; '
'path=/; domain=.app.box.com; secure, cn=89; '
'expires=Fri, 18 Dec 2026 19:59:15 GMT; '
'Max-Age=31536000; path=/; domain=.app.box.com; secure, '
'site_preference=desktop; path=/; domain=.box.com; '
'secure',
'strict-transport-security': 'max-age=31536000',
'via': '1.1 google',
'x-envoy-upstream-service-time': '52'}
Code: None
Context Info:
{}
Request Id: None
Help Url: None
Body:
{ 'error': 'invalid_grant',
'error_description': "Please check the 'jti' claim. A unique 'jti' "
'value is required.'}

Dominant language
Python
Stars
460
Forks
223
Avg merge
14h 18m
Merged PRs (30d)
21

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 box/box-python-sdk

All issues in box/box-python-sdk

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.