Skip to content

fix(models): degrade a non-object Codex auth file to no credential - #5584

Merged
WillemJiang merged 1 commit into
bytedance:mainfrom
BlueX888:fix/prep-credential-file-null-container-crash
Sep 19, 2026
Merged

WillemJiang merged 1 commit into
bytedance:mainfrom
BlueX888:fix/prep-credential-file-null-container-crash

Conversation

@BlueX888

Copy link
Copy Markdown
Contributor

Why

load_codex_cli_credential reads ~/.codex/auth.json (or $CODEX_AUTH_PATH) through _load_json_file, which returns whatever json.loads produced — any valid JSON value, not only an object. The loader then called data.get("tokens", {}) on it directly (backend/packages/harness/deerflow/models/credential_loader.py:229-232).

A syntactically valid auth file whose top level is not an object (an array, a string, a number) therefore raised AttributeError: 'list' object has no attribute 'get' from load_codex_cli_credential. Nothing catches it, so it propagated out of CodexChatModel.model_post_init (openai_codex_provider.py:95), aborting model construction before the provider could raise its documented ValueError("Codex CLI credential not found. Expected ~/.codex/auth.json or CODEX_AUTH_PATH."). That is the opposite of the module's degrade-gracefully behaviour.

The nested tokens value already carries this guard (credential_loader.py:233-235), and the sibling Claude loader got the equivalent top-level guard in #5494 — the Codex top level was the one spot left uncovered.

What changed

  • A Codex auth file whose top level is not a JSON object is now treated as "no credential from this source": one debug log and return None, so the loader falls through and CodexChatModel reaches its existing documented "Codex CLI credential not found" error instead of an AttributeError.
  • Regression tests in backend/tests/test_credential_loader.py:
    • test_load_codex_cli_credential_ignores_non_object_auth_file — parametrized over array / string / number payloads, asserts load_codex_cli_credential() is None.
    • test_codex_chat_model_reports_missing_credential_for_non_object_auth_file — asserts CodexChatModel construction raises the documented ValueError.

Surface area

  • Agents / LangGraph — model construction path (CodexChatModel / credential loading); no prompt-layer data channels affected.

Bug fix verification

  • Test path that reproduces the bug: backend/tests/test_credential_loader.py::test_load_codex_cli_credential_ignores_non_object_auth_file and ::test_codex_chat_model_reports_missing_credential_for_non_object_auth_file
  • Did it go red on main and green on this branch? yes.
    • On main (unpatched): 4 failed, 19 deselected in 0.97s — AttributeError: 'list' object has no attribute 'get' at credential_loader.py:232.
    • On this branch: 23 passed.

Validation

  • cd backend && uv run pytest tests/test_credential_loader.py -q → 23 passed
  • cd backend && uv run pytest -m "not live" --ignore=tests/blocking_io tests/ -q → 17551 passed, 199 skipped, 3 deselected
  • cd backend && uv run ruff check . → All checks passed; uv run ruff format --check . → 1545 files already formatted

AI assistance

Tool(s) used: Claude Code

How you used it: The assistant located the unguarded call, wrote the regression tests, and ran the verification commands quoted above. I reviewed the diff and understand every line.

  • I've read and understand every line of this change and take responsibility for it — it's not unreviewed AI output.

load_codex_cli_credential called .get on the parsed ~/.codex/auth.json
(and $CODEX_AUTH_PATH) without checking that the top level is an object.
_load_json_file returns any valid JSON value, so an array or scalar payload
raised AttributeError out of CodexChatModel.model_post_init instead of the
documented 'Codex CLI credential not found' error. Guard the top level the
same way the sibling Claude loader and its own nested tokens guard do.
@github-actions github-actions Bot added area:backend Gateway / runtime / core backend under backend/ risk:medium Medium risk: regular code changes size/S PR changes 20-100 lines labels Sep 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:backend Gateway / runtime / core backend under backend/ risk:medium Medium risk: regular code changes size/S PR changes 20-100 lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants