fix(deps): bump pydantic to 2.13.4 to avoid pydantic-core thread segfault#29021
Merged
austinpickett merged 2 commits intoMay 20, 2026
Merged
Conversation
…ault
pydantic-core 2.41.5 (pulled by pydantic==2.12.5) segfaults when the
OpenAI SDK's Responses API resource (client.responses.create /
client.responses.stream) is exercised from a non-main threading.Thread.
Hermes always dispatches codex_responses calls from a daemon thread in
agent/chat_completion_helpers.py:_call, so the crash is 100%
reproducible whenever the active provider is xai-oauth or openai-codex.
Symptom: `hermes -z "ping"` (or any oneshot path) dies with SIGSEGV /
exit 139 and zero output — hermes_cli/oneshot.py redirects stderr to
/dev/null, hiding the crash.
Bumping pydantic to 2.13.4 pulls in pydantic-core 2.46.4, which
eliminates the crash. Verified end-to-end: `hermes -z "ping"` against
xai-oauth/grok-4.3 now returns the expected response.
Minimal repro (any OpenAI base_url; not xAI-specific):
import threading
from openai import OpenAI
cli = OpenAI(api_key="sk-bogus", base_url="https://api.openai.com/v1")
def go():
try: cli.responses.create(model="gpt-4o", input="ping")
except BaseException as e: print(type(e).__name__)
threading.Thread(target=go).start()
# → SIGSEGV with pydantic-core 2.41.5; clean 401 with 2.46.4
3 tasks
austinpickett
approved these changes
May 20, 2026
austinpickett
left a comment
Collaborator
There was a problem hiding this comment.
Code Review — fix(deps): bump pydantic to 2.13.4 to avoid pydantic-core thread segfault
2 actual files changed (pyproject.toml + uv.lock). 47 of 49 files in the diff are merge noise from main.
Assessment
- pydantic: 2.12.5 → 2.13.4 (minor version bump)
- pydantic-core (transitive): 2.41.5 → 2.46.4 (5 minor versions forward with thread-safety fixes)
- Consistent with project's strict
==X.Y.Zexact-pin convention - All transitive consumers (openai, mcp, honcho-ai, pydantic-settings) use
>=lower bounds satisfied by 2.13.4 - Commit message is exemplary — includes minimal repro, identifies exact call site (
chat_completion_helpers.py:_callfrom daemon thread), confirms end-to-end verification
Breaking change risk: Low
Pydantic follows semver. Minor bump, lockfile resolved cleanly with no conflicts.
Suggestion (non-blocking)
Consider adding a CI smoke test that exercises model validation from a non-main thread to prevent this class of segfault from regressing if pydantic-core is ever downgraded.
Verdict: LGTM — clean, focused, well-documented fix for a real crash.
Reviewed by Hermes Agent
dannyJ848
pushed a commit
to dannyJ848/hermes-agent
that referenced
this pull request
May 21, 2026
…ault (NousResearch#29021) * fix(deps): bump pydantic to 2.13.4 to avoid pydantic-core thread segfault pydantic-core 2.41.5 (pulled by pydantic==2.12.5) segfaults when the OpenAI SDK's Responses API resource (client.responses.create / client.responses.stream) is exercised from a non-main threading.Thread. Hermes always dispatches codex_responses calls from a daemon thread in agent/chat_completion_helpers.py:_call, so the crash is 100% reproducible whenever the active provider is xai-oauth or openai-codex. Symptom: `hermes -z "ping"` (or any oneshot path) dies with SIGSEGV / exit 139 and zero output — hermes_cli/oneshot.py redirects stderr to /dev/null, hiding the crash. Bumping pydantic to 2.13.4 pulls in pydantic-core 2.46.4, which eliminates the crash. Verified end-to-end: `hermes -z "ping"` against xai-oauth/grok-4.3 now returns the expected response. Minimal repro (any OpenAI base_url; not xAI-specific): import threading from openai import OpenAI cli = OpenAI(api_key="sk-bogus", base_url="https://api.openai.com/v1") def go(): try: cli.responses.create(model="gpt-4o", input="ping") except BaseException as e: print(type(e).__name__) threading.Thread(target=go).start() # → SIGSEGV with pydantic-core 2.41.5; clean 401 with 2.46.4 * chore(deps): regenerate uv.lock for pydantic 2.13.4 bump
Lillard01
pushed a commit
to Lillard01/hermes-agent
that referenced
this pull request
May 21, 2026
…ault (NousResearch#29021) * fix(deps): bump pydantic to 2.13.4 to avoid pydantic-core thread segfault pydantic-core 2.41.5 (pulled by pydantic==2.12.5) segfaults when the OpenAI SDK's Responses API resource (client.responses.create / client.responses.stream) is exercised from a non-main threading.Thread. Hermes always dispatches codex_responses calls from a daemon thread in agent/chat_completion_helpers.py:_call, so the crash is 100% reproducible whenever the active provider is xai-oauth or openai-codex. Symptom: `hermes -z "ping"` (or any oneshot path) dies with SIGSEGV / exit 139 and zero output — hermes_cli/oneshot.py redirects stderr to /dev/null, hiding the crash. Bumping pydantic to 2.13.4 pulls in pydantic-core 2.46.4, which eliminates the crash. Verified end-to-end: `hermes -z "ping"` against xai-oauth/grok-4.3 now returns the expected response. Minimal repro (any OpenAI base_url; not xAI-specific): import threading from openai import OpenAI cli = OpenAI(api_key="sk-bogus", base_url="https://api.openai.com/v1") def go(): try: cli.responses.create(model="gpt-4o", input="ping") except BaseException as e: print(type(e).__name__) threading.Thread(target=go).start() # → SIGSEGV with pydantic-core 2.41.5; clean 401 with 2.46.4 * chore(deps): regenerate uv.lock for pydantic 2.13.4 bump
Gpapas
pushed a commit
to Gpapas/hermes-agent
that referenced
this pull request
May 23, 2026
…ault (NousResearch#29021) * fix(deps): bump pydantic to 2.13.4 to avoid pydantic-core thread segfault pydantic-core 2.41.5 (pulled by pydantic==2.12.5) segfaults when the OpenAI SDK's Responses API resource (client.responses.create / client.responses.stream) is exercised from a non-main threading.Thread. Hermes always dispatches codex_responses calls from a daemon thread in agent/chat_completion_helpers.py:_call, so the crash is 100% reproducible whenever the active provider is xai-oauth or openai-codex. Symptom: `hermes -z "ping"` (or any oneshot path) dies with SIGSEGV / exit 139 and zero output — hermes_cli/oneshot.py redirects stderr to /dev/null, hiding the crash. Bumping pydantic to 2.13.4 pulls in pydantic-core 2.46.4, which eliminates the crash. Verified end-to-end: `hermes -z "ping"` against xai-oauth/grok-4.3 now returns the expected response. Minimal repro (any OpenAI base_url; not xAI-specific): import threading from openai import OpenAI cli = OpenAI(api_key="sk-bogus", base_url="https://api.openai.com/v1") def go(): try: cli.responses.create(model="gpt-4o", input="ping") except BaseException as e: print(type(e).__name__) threading.Thread(target=go).start() # → SIGSEGV with pydantic-core 2.41.5; clean 401 with 2.46.4 * chore(deps): regenerate uv.lock for pydantic 2.13.4 bump
Mucky010
pushed a commit
to Mucky010/hermes-agent
that referenced
this pull request
May 24, 2026
…ault (NousResearch#29021) * fix(deps): bump pydantic to 2.13.4 to avoid pydantic-core thread segfault pydantic-core 2.41.5 (pulled by pydantic==2.12.5) segfaults when the OpenAI SDK's Responses API resource (client.responses.create / client.responses.stream) is exercised from a non-main threading.Thread. Hermes always dispatches codex_responses calls from a daemon thread in agent/chat_completion_helpers.py:_call, so the crash is 100% reproducible whenever the active provider is xai-oauth or openai-codex. Symptom: `hermes -z "ping"` (or any oneshot path) dies with SIGSEGV / exit 139 and zero output — hermes_cli/oneshot.py redirects stderr to /dev/null, hiding the crash. Bumping pydantic to 2.13.4 pulls in pydantic-core 2.46.4, which eliminates the crash. Verified end-to-end: `hermes -z "ping"` against xai-oauth/grok-4.3 now returns the expected response. Minimal repro (any OpenAI base_url; not xAI-specific): import threading from openai import OpenAI cli = OpenAI(api_key="sk-bogus", base_url="https://api.openai.com/v1") def go(): try: cli.responses.create(model="gpt-4o", input="ping") except BaseException as e: print(type(e).__name__) threading.Thread(target=go).start() # → SIGSEGV with pydantic-core 2.41.5; clean 401 with 2.46.4 * chore(deps): regenerate uv.lock for pydantic 2.13.4 bump
Bryce-huang
pushed a commit
to wbkunlun/hermes-agent
that referenced
this pull request
May 29, 2026
…ault (NousResearch#29021) * fix(deps): bump pydantic to 2.13.4 to avoid pydantic-core thread segfault pydantic-core 2.41.5 (pulled by pydantic==2.12.5) segfaults when the OpenAI SDK's Responses API resource (client.responses.create / client.responses.stream) is exercised from a non-main threading.Thread. Hermes always dispatches codex_responses calls from a daemon thread in agent/chat_completion_helpers.py:_call, so the crash is 100% reproducible whenever the active provider is xai-oauth or openai-codex. Symptom: `hermes -z "ping"` (or any oneshot path) dies with SIGSEGV / exit 139 and zero output — hermes_cli/oneshot.py redirects stderr to /dev/null, hiding the crash. Bumping pydantic to 2.13.4 pulls in pydantic-core 2.46.4, which eliminates the crash. Verified end-to-end: `hermes -z "ping"` against xai-oauth/grok-4.3 now returns the expected response. Minimal repro (any OpenAI base_url; not xAI-specific): import threading from openai import OpenAI cli = OpenAI(api_key="sk-bogus", base_url="https://api.openai.com/v1") def go(): try: cli.responses.create(model="gpt-4o", input="ping") except BaseException as e: print(type(e).__name__) threading.Thread(target=go).start() # → SIGSEGV with pydantic-core 2.41.5; clean 401 with 2.46.4 * chore(deps): regenerate uv.lock for pydantic 2.13.4 bump #AI commit#
gweeteve
pushed a commit
to gweeteve/hermes-agent
that referenced
this pull request
Jun 2, 2026
…ault (NousResearch#29021) * fix(deps): bump pydantic to 2.13.4 to avoid pydantic-core thread segfault pydantic-core 2.41.5 (pulled by pydantic==2.12.5) segfaults when the OpenAI SDK's Responses API resource (client.responses.create / client.responses.stream) is exercised from a non-main threading.Thread. Hermes always dispatches codex_responses calls from a daemon thread in agent/chat_completion_helpers.py:_call, so the crash is 100% reproducible whenever the active provider is xai-oauth or openai-codex. Symptom: `hermes -z "ping"` (or any oneshot path) dies with SIGSEGV / exit 139 and zero output — hermes_cli/oneshot.py redirects stderr to /dev/null, hiding the crash. Bumping pydantic to 2.13.4 pulls in pydantic-core 2.46.4, which eliminates the crash. Verified end-to-end: `hermes -z "ping"` against xai-oauth/grok-4.3 now returns the expected response. Minimal repro (any OpenAI base_url; not xAI-specific): import threading from openai import OpenAI cli = OpenAI(api_key="sk-bogus", base_url="https://api.openai.com/v1") def go(): try: cli.responses.create(model="gpt-4o", input="ping") except BaseException as e: print(type(e).__name__) threading.Thread(target=go).start() # → SIGSEGV with pydantic-core 2.41.5; clean 401 with 2.46.4 * chore(deps): regenerate uv.lock for pydantic 2.13.4 bump
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Bumps
pydanticfrom2.12.5→2.13.4(pulling inpydantic-core2.41.5→2.46.4) to fix a hard SIGSEGV that crashes every codex_responses dispatch path (xai-oauth,openai-codex).pydantic-core==2.41.5segfaults when the OpenAI SDK's Responses API resource (client.responses.create(...)/client.responses.stream(...)) is exercised from a non-mainthreading.Thread. Hermes always wraps codex calls inthreading.Thread(target=_call, daemon=True)atagent/chat_completion_helpers.py:159, so the crash is 100% reproducible whenever the active provider usesapi_mode=codex_responses.The crash is silent to end users because
hermes_cli/oneshot.py:174-188redirects both stdout and stderr to/dev/nullfor the entire call tree. Operator symptom:hermes -z "ping"exits with no output; undertimeoutthe harness reportsdumped core/ exit 139.Minimal repro (no Hermes, just the venv)
The same script using
cli.chat.completions.create(stream=True)from a thread works — bug is specific to the Responses resource × pydantic-core 2.41.5 × non-main thread.Bisection
Diff between a fresh-venv (no crash) and the Hermes venv (crash) was isolated to pydantic-core alone —
anyio,jiter,certifi,idna,httpx, etc. were ruled out individually.Test plan
hermes -z "ping"against xai-oauth / grok-4.3 no longer SIGSEGVs (validated end-to-end in the Hermes venv on Linux x86_64 musl)_run_agent("ping", model="grok-4.3", provider="xai-oauth")returns'pong'instead of crashingpip install --dry-run pydantic==2.13.4in the Hermes venv touches onlypydantic+pydantic-core; all other pinned deps already satisfy 2.13.4's constraints (annotated-types>=0.6.0,typing-extensions>=4.14.1,typing-inspection>=0.4.2)Platforms tested
Related diagnosability concern (not fixed here)
Worth a follow-up:
hermes_cli/oneshot.py:174-188swallows stderr unconditionally, which is what made this a multi-hour investigation instead of a 30-second triage. Even withPYTHONFAULTHANDLER=1, the C-level stack never reaches the operator. Two cheap improvements would dramatically improve future SIGSEGV diagnosability:tailit to the real stderr on non-zero exit (instead of/dev/null).faulthandler.enable(file=open(<known path>, "w"), all_threads=True)before the redirect block.Happy to send these as a separate PR if you'd like.
🤖 Generated with Claude Code