{"record":{"id":"7999e6187b220a0a","repo":"clockworklabs/SpacetimeDB","slug":"unexpected-error-from-datastore-index-scan-range","errorCode":null,"errorMessage":"unexpected error from `datastore_index_scan_range_bsatn`: {e}","messagePattern":"unexpected error from `datastore_index_scan_range_bsatn`: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/bindings/src/table.rs","lineNumber":991,"sourceCode":"/// Performs a ranged scan using the range arguments `B` in `Tbl` using `Idx`.\n///\n/// The type parameter `K` is either `()` or [`SingleBound`]\n/// and is used to workaround the orphan rule.\nfn filter<Tbl, Idx, IndexType, B, K>(b: B) -> impl Iterator<Item = Tbl::Row>\nwhere\n    Tbl: Table,\n    Idx: Index,\n    B: IndexScanRangeBounds<IndexType, K>,\n{\n    let index_id = Idx::index_id();\n\n    let iter = if const { is_point_scan::<Idx, B, _, _>() } {\n        b.with_point_arg(|point| datastore_index_scan_point_bsatn(index_id, point))\n    } else {\n        let args = b.get_range_args();\n        let (prefix, prefix_elems, rstart, rend) = args.args_for_syscall();\n        sys::datastore_index_scan_range_bsatn(index_id, prefix, prefix_elems, rstart, rend)\n            .unwrap_or_else(|e| panic!(\"unexpected error from `datastore_index_scan_range_bsatn`: {e}\"))\n    };\n\n    TableIter::new(iter)\n}\n\n/// A read-only handle to a B-tree or Direct index.\n///\n/// This is the read-only version of [`RangedIndex`].\n/// It mirrors [`RangedIndex`] but exposes only `.filter(..)`, not `.delete(..)`.\n/// It is used by `{table}__ViewHandle` to keep view code read-only at compile time.\n///\n/// Note, the `Tbl` generic is the read-write table handle `{table}__TableHandle`.\n/// This is because read-only indexes still need [`Table`] metadata.\n/// The view handle itself deliberately does not implement `Table`.\npub struct RangedIndexReadOnly<Tbl: Table, IndexType, Idx: Index> {\n    _marker: PhantomData<(Tbl, IndexType, Idx)>,\n}\n","sourceCodeStart":973,"sourceCodeEnd":1009,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/6dee26c6efc2856793e12b148a59742964f5d783/crates/bindings/src/table.rs#L973-L1009","documentation":"Raised inside a SpacetimeDB reducer when `datastore_index_scan_range_bsatn` — the syscall backing ranged index reads — fails unexpectedly. It fires from the shared `filter` helper used by both `RangedIndex::filter` and the read-only `RangedIndexReadOnly::filter` on view handles. The bindings treat every non-OK errno from a range scan as a bug or an environment mismatch, so this panic indicates host/module disagreement or a host error, not bad range syntax (type errors are caught at compile time).","triggerScenarios":"Iterating an index with a non-point range, e.g. `ctx.db.user().dogs_and_name().filter(25u64..)` or `filter((25u64, \"J\"..\"K\"))`, when the host cannot perform the scan: module schema out of sync with the database, bindings/server version mismatch, or resource exhaustion inside the host while opening the row iterator.","commonSituations":"Reading from a `{table}__ViewHandle` inside view code after the underlying table's index changed without republish; long-running servers upgraded independently of deployed modules; integration tests hitting a host bug.","solutions":["Republish the module against the current database so index definitions match: `spacetime publish <db>`; if schema evolution is involved, publish to a fresh database to confirm.","Pin matching versions of `spacetimedb-bindings` and the spacetimedb server/CLI you run.","Narrow the range (or split it into batches) to rule out oversized scans stressing the host.","Persist the errno `{e}` from the panic and file an issue with SpacetimeDB if versions already match — the code path considers this state unreachable."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":"let scan = std::panic::catch_unwind(|| {\n    ctx.db.user().dogs_and_name().filter(25u64..).collect::<Vec<_>>()\n});\nmatch scan {\n    Ok(rows) => { /* use rows */ }\n    Err(panic) => { log::error!(\"index scan failed: {panic:?}\"); return Err(\"internal scan failure\".into()); }\n}","preventionTips":["Pin bindings and server versions together in your CI so they cannot drift.","Republish modules whenever index definitions change so scan syscalls match the live schema.","Prefer narrow ranges and verify index usage in tests before promoting to production."],"tags":["spacetimedb","reducer-panic","index-scan","range-query","host-syscall"],"backgroundTag":"host-syscall-unexpected-error","analyzedSha":"6dee26c6efc2856793e12b148a59742964f5d783","analyzedAt":"2026-08-20T06:08:37.179Z","contentChangedAt":"2026-08-20T06:08:37.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}