Skip to content

Handle non-entity table loads in TestIndexer - #1324

Merged
DZakh merged 6 commits into
mainfrom
claude/happy-meitner-ijoe5w
Jun 15, 2026
Merged

Handle non-entity table loads in TestIndexer#1324
DZakh merged 6 commits into
mainfrom
claude/happy-meitner-ijoe5w

Conversation

@DZakh

@DZakh DZakh commented Jun 15, 2026

Copy link
Copy Markdown
Member

Summary

Fix a crash in TestIndexer when loading cached effect tables during batch splits. The handleLoad function assumed all loaded tables were entity tables with corresponding configs, but effect cache tables (named envio_effect_<name>) are never persisted by TestIndexer and lack configs.

Changes

  • TestIndexer.res: Wrap handleLoad logic in a switch that checks if the table has an entity config. Return an empty result for non-entity tables (effect caches) instead of crashing when trying to access the missing config.
  • EventHandlers.ts: Add test case registerAndCachedEffect that reproduces the cross-batch cached-effect load scenario by registering a dynamic contract at a later block, which splits processing into two batches.
  • EventHandler.test.ts: Add regression test that verifies TestIndexer doesn't crash when a cached effect's cache is loaded back in a batch split off by a later contract registration.

Implementation Details

When a dynamic contract is registered at a later block than a prior event, processing splits into two batches. The second batch's preload attempts to load the effect cache from storage. TestIndexer now gracefully handles this by returning an empty result, allowing the effect to recompute rather than crashing on the missing config.

https://claude.ai/code/session_01VifhCAyRnCa5Z2CW2T3rri

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Enhanced handling of table loads for non-persisted cache tables to prevent unsafe lookups.
  • Tests

    • Added regression test for cached effect loading scenarios across transaction batches.

claude added 4 commits June 12, 2026 15:41
…ed-effect load

createTestIndexer().process() throws `TypeError: Cannot read properties of
undefined (reading 'table')` from TestIndexer.handleLoad when a cached effect's
cache is loaded back in a later batch.

handleLoad looks up `state.entityConfigs[tableName]` and unconditionally reads
`.table`. Every entity load passes the entity's own table name (always present
in entityConfigs), so the "read an entity back" framing in the report is a red
herring. The one loadOrThrow whose table is not an entity is the cached-effect
load (LoadLayer.loadByEffect -> effect.storageMeta.table, table name
`envio_effect_<EffectName>`); that name is absent from entityConfigs, so the
lookup is undefined and `.table` throws.

The load only fires once the effect cache has been committed by an earlier batch
and a later batch requests a not-yet-in-memory cache key, i.e. a multi-batch run
with a cached effect. Single-batch simulate runs never hit it, matching the
report. The repro sets full_batch_size: 1 so a two-block simulate splits into
two batches the way a real multi-block indexer does.

https://claude.ai/code/session_01VifhCAyRnCa5Z2CW2T3rri
…uite

Keeps the cross-batch cached-effect load case but drops the repro-specific
naming so future TestIndexer cases can live in the same file.

https://claude.ai/code/session_01VifhCAyRnCa5Z2CW2T3rri
The earlier reproduction forced multiple batches with full_batch_size: 1.
Verified against the real reporter repo (enviodev/safe-analysis-indexer, envio
3.2.0, no batch-size config): the crash reproduces naturally. Tracing it there
showed the failing SafeSetup→ProxyCreation case commits the first block as its
own batch (WRITEBATCH [50]) and then crashes loading
`envio_effect_getSafeCreatorViaTraceTransaction` in the second batch — i.e. the
split comes from ProxyCreation registering a dynamic contract one block after a
prior event, not from any batch-size setting.

Drop full_batch_size: 1 and reproduce the split the same way: a plain event at
block 2 caches the effect (batch 1 commits), then a contractRegister event at
block 3 runs in the split-off batch and re-calls the cached effect with a fresh
key, whose preload loads the effect-cache table and hits the missing
entityConfig.

https://claude.ai/code/session_01VifhCAyRnCa5Z2CW2T3rri
handleLoad assumed every load targets a registered entity and dereferenced
state.entityConfigs[tableName].table. The cached-effect load passes the
effect-cache table (envio_effect_<name>), which isn't an entity, so the lookup
was undefined and .table threw "Cannot read properties of undefined (reading
'table')". TestIndexer never persists effect caches, so return an empty result
for non-entity tables and let the effect recompute.

Move the reproduction into EventHandler.test.ts (the existing TestIndexer test
file) so all TestIndexer cases live in one place, and compact its comment.

https://claude.ai/code/session_01VifhCAyRnCa5Z2CW2T3rri
@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 91a0aa3a-bde1-4e71-b334-4706c49f81ea

📥 Commits

Reviewing files that changed from the base of the PR and between 43e9bf8 and 7a5e1c4.

📒 Files selected for processing (3)
  • packages/envio/src/TestIndexer.res
  • scenarios/test_codegen/src/handlers/EventHandlers.ts
  • scenarios/test_codegen/test/EventHandler.test.ts

📝 Walkthrough

Walkthrough

handleLoad in TestIndexer.res is updated to return an empty JSON array for tables absent from state.entityConfigs (e.g., cached-effect tables), preventing a crash. A new registerAndCachedEffect handler case and a regression test validate that loading a cached effect after a contract-registration-triggered batch split no longer rejects.

Changes

Cached effect load safety fix and regression test

Layer / File(s) Summary
Safe handleLoad for missing entity configs
packages/envio/src/TestIndexer.res
handleLoad now switches on state.entityConfigs for tableName; returns an empty JSON array when no schema is found, and runs the existing entity-load/filter/serialize path only when a config is present.
registerAndCachedEffect handler case and regression test
scenarios/test_codegen/src/handlers/EventHandlers.ts, scenarios/test_codegen/test/EventHandler.test.ts
Adds a FactoryEvent switch case that calls context.chain.SimpleNft.add and a corresponding main-handler branch that calls testEffectWithCache({id:"3"}) and asserts "test-3"; a regression test drives both across two blocks with a batch split and asserts doesNotReject.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • enviodev/hyperindex#1306: Directly precedes this PR — it refactored handleLoad to use EntityFilter.matches, which is the same function this PR extends to handle the missing-entityConfig case.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: handling non-entity tables (specifically effect cache tables) in TestIndexer's handleLoad function, which is the core fix that prevents crashes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Comment @coderabbitai help to get the list of available commands and usage tips.

@DZakh
DZakh enabled auto-merge (squash) June 15, 2026 11:38
@DZakh
DZakh merged commit dc27367 into main Jun 15, 2026
8 checks passed
@DZakh
DZakh deleted the claude/happy-meitner-ijoe5w branch June 15, 2026 11:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants