Repository navigation
fix(core): make missing checkpoint threadId observable and optionally strict - #163
Merged
yuluo-yx merged 1 commit intoOct 15, 2026
Conversation
… strict When RunnableConfig has no threadId, BaseCheckpointSaver#checkpointThreadId silently fell back to the shared $default namespace, so unrelated callers on the same saver instance could read each other's checkpoints without any log or error (issue agentic-ai-java#154, originally alibaba/spring-ai-alibaba#4975). - Log a one-shot warning when a config falls back to the shared default namespace (scoped by app_name/user_id metadata when present). - Add CheckpointThreadIdPolicy with an opt-in strict mode enabled via the argi.checkpoint.requireExplicitThreadId system property or setRequireExplicitThreadId(true); checkpoint operations then fail fast with IllegalArgumentException until the caller provides a threadId. - Add offline regression tests covering the shared-bucket reproduction on MemorySaver, the strict policy, per-identity scoping with app/user metadata, and the shared rule across saver implementations. - Document the $default sharing semantics and the strict-mode switch in the argi-graph-core README and the checkpointThreadId javadoc. Fixes agentic-ai-java#154
Carl-Zhou-CN
force-pushed
the
fix/154-checkpoint-default-thread-namespace
branch
from
October 15, 2026 04:10
f9dd7ba to
4553c6f
Compare
Aias00
approved these changes
Oct 15, 2026
Aias00
left a comment
Contributor
There was a problem hiding this comment.
Review: fix(core): make missing checkpoint threadId observable and optionally strict (#154)
Verdict: APPROVE
This is a clean, well-scoped fix for a real cross-caller data-sharing / observability gap (issue #154): an omitted threadId silently fell back to the shared $default bucket, so unrelated callers on the same saver instance could read each other's checkpoints.
What's good
checkpointThreadIdis the single chokepoint and cannot be bypassed. I verified every saver implementation routes through it:MemorySaver,RedisSaver,MongoSaver,FileSystemSaver,VersionedMemorySaver, andMemoryLeasedCheckpointSavercall it directly;H2Saver/MysqlSaver/OracleSaver/PostgresSaverinherit it viaAbstractJdbcCheckpointSaver(none overrideget/put/list). So the warning + strictIllegalArgumentExceptionfire uniformly on every saver operation.- One-shot warning (
AtomicBoolean, never floods logs) plus a clear strict-mode error that names theargi.checkpoint.requireExplicitThreadIdproperty. - Solid regression suite: shared-bucket reproduction, strict rejects
get/put/list/checkpointThreadId, strict accepts an explicit id, per-identity scoping, strict-rejects-even-with-metadata, cross-saver.@AfterEachrestores the policy for test isolation. - README + javadoc document the
$defaultsharing semantics and the strict switch.
Non-blocking nits
- Javadoc on
setRequireExplicitThreadId(false)says it "restores the startup default derived from the property," but the implementation sets the field to the passed value unconditionally (does not re-read the property). Minor doc/behavior mismatch — the test's restore helper correctly re-reads it. requireExplicitThreadIdis a JVM-global mutable static. Fine for tests, but for production prefer the system-property form (immutable at startup) so one caller can't flip it process-wide.- The PR body mentions "a lint-script skip for the machine-local
.awrruntime directory," but that change is not in the diff (only 4 checkpoint-related files). Confirm it landed in another PR or drop it from the description. migrateLegacyThreadstill computeslegacyThreadIdviaconfig.threadId().orElse(THREAD_ID_DEFAULT)directly before validating viacheckpointThreadId; a legacy config with no threadId won't trigger the new warning on that path. Minor / intended (migration path).
No CI checks were reported on the branch at review time; the included offline suite is sufficient.
yuluo-yx
pushed a commit
that referenced
this pull request
Oct 17, 2026
… strict (#163) When RunnableConfig has no threadId, BaseCheckpointSaver#checkpointThreadId silently fell back to the shared $default namespace, so unrelated callers on the same saver instance could read each other's checkpoints without any log or error (issue #154, originally alibaba/spring-ai-alibaba#4975). - Log a one-shot warning when a config falls back to the shared default namespace (scoped by app_name/user_id metadata when present). - Add CheckpointThreadIdPolicy with an opt-in strict mode enabled via the argi.checkpoint.requireExplicitThreadId system property or setRequireExplicitThreadId(true); checkpoint operations then fail fast with IllegalArgumentException until the caller provides a threadId. - Add offline regression tests covering the shared-bucket reproduction on MemorySaver, the strict policy, per-identity scoping with app/user metadata, and the shared rule across saver implementations. - Document the $default sharing semantics and the strict-mode switch in the argi-graph-core README and the checkpointThreadId javadoc. Fixes #154
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.
Contributing to ARGI: when RunnableConfig omits threadId, checkpoint savers now log a one-shot warning instead of silently sharing the "$default" namespace, and an opt-in strict policy (argi.checkpoint.requireExplicitThreadId=true or CheckpointThreadIdPolicy.setRequireExplicitThreadId(true)) makes checkpoint operations fail fast until an explicit threadId is provided; includes offline regression tests for MemorySaver and VersionedMemoryCheckpointSaver, README documentation of the shared $default semantics, and a lint-script skip for the machine-local .awr runtime directory. Fixes #154