Skip to content

fix(state): log disk state files that fail to load instead of ignoring them - #7631

Open
gaurav0107 wants to merge 2 commits into
reflex-dev:mainfrom
gaurav0107:fix/7167-statemanagerdisk-silently-resets-corrupt
Open

gaurav0107 wants to merge 2 commits into
reflex-dev:mainfrom
gaurav0107:fix/7167-statemanagerdisk-silently-resets-corrupt

Conversation

@gaurav0107

@gaurav0107 gaurav0107 commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

All Submissions:

  • Have you followed the guidelines stated in CONTRIBUTING.md file?
  • Have you checked to ensure there aren't any other open Pull Requests for the desired changed?

Type of change

  • Bug fix (non-breaking change which fixes an issue)

Description

StateManagerDisk.load_state() caught every exception and returned None, so an existing state file that could not be loaded was handled like a missing one. get_state() started from a fresh state and the next write replaced the file, and nothing was logged.

This PR keeps the return value (still None, so the app keeps working from a fresh state, as the redis manager does on a mismatch) but makes the failure visible:

  • File that cannot be read or unpickled (bad pickle bytes, truncated or empty file, a pickle referencing a missing module, IO errors): a warning that names the token and file path, with the traceback.
  • Stored schema no longer matches the state class (StateSchemaMismatchError with no chained cause): a debug record. This is an expected reset after editing a state class in dev, and a warning here would fire for every stale substate after each edit.
  • Missing file: unchanged, no log.

BaseState._deserialize also raises StateSchemaMismatchError for unpickling failures, but chains the original error, so a mismatch counts as an expected reset only when it has no chained cause.

I kept this to logging and didn't add a new exception or quarantine the file, because the issue doesn't settle the recovery behavior. If you'd prefer to raise, or to move the unreadable file aside before it gets overwritten, I can change it.

Closes #7167

Changes To Core Features:

  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your core changes, as applicable?
  • Have you successfully ran tests with your changes locally?

Testing

New tests in tests/units/istate/manager/test_disk.py. All of them fail on main:

  • missing file: load_state returns None and logs nothing
  • unreadable file (b"not-a-pickle" and an empty file for both a plain StateToken and a BaseStateToken, plus a pickle that references a missing module): one WARNING that names the token and path and carries exc_info, and get_state still returns a fresh state
  • stale schema (a valid pickle whose stored schema doesn't match): one DEBUG record, no warning, and get_state returns defaults

Commands run:

  • uv run pytest tests/units/istate/manager: 75 passed
  • uv run pytest tests/units --cov --no-cov-on-fail --cov-report=: the only 3 failures also fail on main in my environment (two dataeditor tests need node, one reflex_bench HMR port test)
  • uv run pre-commit run --files <changed files> (ruff format/check, codespell, pyright, ty): all pass

🤖 Opened with Superhuman, an open-source contribution agent.

…g them

StateManagerDisk.load_state swallowed every exception, so an existing state
file that could not be read looked exactly like a missing one: get_state
started from a fresh state and the next write replaced the file, with
nothing in the logs.

A damaged or unreadable file is now logged as a warning with the traceback.
A state class that changed since the file was written is still an expected
reset (as in the redis manager) and is logged at debug level. BaseState
reports both as StateSchemaMismatchError, so the unpickling cause tells
them apart.

Closes reflex-dev#7167
@greptile-apps

greptile-apps Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge.

Summary

The disk state manager now reports failed loads without changing how it starts from fresh state.

  • Disk state load failures now show up in the logs.

No new actionable issues were found. No previous review threads were supplied.

Reviews (2) · Last reviewed commit: "fix(state): warn on any disk state file ..." · Reviewed by Greptile

@gaurav0107
gaurav0107 marked this pull request as ready for review October 22, 2026 12:29
@gaurav0107
gaurav0107 requested a review from a team as a code owner October 22, 2026 12:29
@codspeed

codspeed Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Merging this PR will regress 1 benchmark

2 warnings

⚠️ 9 benchmarks are dominated by system calls

System calls cannot be simulated consistently and are left out of the measure. The reported value understates the real cost. Switch to the Walltime instrument to measure them.

Learn more about system calls

See affected benchmarks

⚠️ Base and head ran on different runner types

Some benchmarks with significant performance changes were compared across different runner types, so the changes might not come from the code. Run base and head on the same runner type, or use CodSpeed Macro Runners for more stable results.

Learn more about Macro Runners

Open the report in CodSpeed to investigate

⚡ 1 improved benchmark
❌ 1 regressed benchmark
✅ 146 untouched benchmarks

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
❌ test_get_state_uncached[memory] 8.1 ms 8.5 ms -4.48%
⚡ test_route_argument_extraction 120.6 µs 114.5 µs +5.31%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing gaurav0107:fix/7167-statemanagerdisk-silently-resets-corrupt (bf6cee2) with main (be0c685)

Open in CodSpeed

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 3 files

Reply with feedback, questions, or to request a fix.

View guided diff | Re-trigger cubic

Comment thread reflex/istate/manager/disk.py Outdated
Comment thread tests/units/istate/manager/test_disk.py
Comment thread news/+disk-state-load-errors.bugfix.md Outdated
Treat a StateSchemaMismatchError as an expected reset only when it has no
chained cause. BaseState._deserialize chains every unpickling failure, so a
pickle referencing a missing module is now a warning too, not only a
truncated or garbled file. Also assert the token in the warning and tighten
the changelog wording.
@masenf masenf added the bug Something isn't working label Oct 22, 2026 — with ChatGPT Codex Connector

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

StateManagerDisk silently resets corrupted persisted state

2 participants