# \[Bug\]: ChatGPT connections end after an hour because every refresh returns invalid_grant · Issue \#14356 · pingdotgg/t3code

[View on GitCafe](https://git.cafe/pingdotgg/t3code/issues/14356)

Repository: [pingdotgg/t3code](https://git.cafe/pingdotgg/t3code)

Visibility: public

State: completed

Priority: 0

## Description

[Discussion and activity](https://git.cafe/pingdotgg/t3code/issues/14356)

---

> **This issue is AI-generated.** An AI coding agent wrote it from our own reproduction against OpenAI's token endpoint. We have not run T3 Code itself; the T3 Code behavior below is read from its source.

### Before submitting

- [x] I searched existing issues and did not find a duplicate.
- [x] I included enough detail to reproduce or investigate the problem.

### Area

apps/server

### Steps to reproduce

1. Connect a ChatGPT account with managed authentication (#14290).
2. Keep the connection past the access token's one-hour lifetime. `CodexChatGptAuth` renews it within 60 seconds of expiry, once `earliest_refresh_at` has passed ([CodexChatGptAuth.ts L729-L748](https://github.com/pingdotgg/t3code/blob/0fcd5f90611451cca842689faea53b5450c022da/apps/server/src/provider/CodexChatGptAuth.ts#L729-L748)).
3. OpenAI refuses the renewal.

Without T3 Code: take a token set from any client of this flow and, inside the renewal window, send the same request:

```sh
curl -sS https://auth.openai.com/api/accounts/oauth/token \
  --data-urlencode grant_type=refresh_token \
  --data-urlencode client_id="$ISSUED_CLIENT_ID" \
  --data-urlencode refresh_token="$REFRESH_TOKEN" \
  --data-urlencode resource=https://api.openai.com/v1
```

### Expected behavior

HTTP 200 with a new access token and a replacement refresh token, so the connection stays up.

### Actual behavior

OpenAI answers `400 {"error": "invalid_grant"}` with no `error_description`. T3 Code treats `invalid_grant` on a refresh as a dead token ([L391-L406](https://github.com/pingdotgg/t3code/blob/0fcd5f90611451cca842689faea53b5450c022da/apps/server/src/provider/CodexChatGptAuth.ts#L391-L406)): it removes the connection and shows "Your ChatGPT connection expired or was disconnected. Sign in again." So every connection should end about an hour after sign-in.

We sent this request eight times across three sign-ins: before and after `earliest_refresh_at`, 60 seconds before expiry (T3 Code's timing), after expiry, and with `ext_agent_host_id` or `scope` added or `resource` dropped (those three reused a token that had just been refused). Every one was refused, including never-used tokens inside the renewal window. pi and nolune send the same four fields.

### Impact

Major degradation or frequent failure

### Version or commit

main @ 0fcd5f9

### Environment

Not environment-specific: the refusal comes from OpenAI's token endpoint. Reproduced with curl and Python on macOS.

### Logs or stack traces

```shell
HTTP/1.1 400 Bad Request

{"error": "invalid_grant"}
```

### Workaround

Sign in again when the connection ends. T3 Code's request matches the documented one, so there may be nothing to change here unless OpenAI says a refresh needs more.

Full report, with every attempt, a reproduction script, and the refresh code of T3 Code, pi and nolune: https://github.com/justrach/codegraff/blob/feat/chat-gpt-new/docs/upstream/openai-sign-in-refresh-invalid-grant.md

Tracked for graff in https://github.com/justrach/codegraff/issues/1422.

