clockworklabs/SpacetimeDB · error
data key not found in return object
Error message
data key not found in return object
What it means
For ABI-v2 view calls the host expects __call_view_anon__ to return an object with a `data` field containing a Uint8Array of encoded rows. This error means the object came back without a readable `data` property — an envelope-shape mismatch between the module's v2 bindings and the host's protocol. The view may have run fine; its result simply cannot be decoded.
Source
Thrown at crates/core/src/host/v8/syscall/v2.rs:556
args: view_args,
} = op;
// Serialize the arguments.
let view_id = serialize_to_js(scope, &view_id)?;
let sender = serialize_to_js(scope, &sender.to_u256())?;
let view_args = serialize_to_js(scope, view_args.get_bsatn())?;
let args = &[view_id, sender, view_args];
// Call the function.
let ret = call_recv_fun(scope, fun, hooks.recv, args)?;
// Returns an object with a `data` field containing the bytes.
let ret = cast!(scope, ret, v8::Object, "object return from `__call_view_anon__`").map_err(|e| e.throw(scope))?;
let Some(data_key) = v8::String::new(scope, "data") else {
return Err(ErrorOrException::Err(anyhow::anyhow!("error creating a v8 string")));
};
let Some(data_val) = ret.get(scope, data_key.into()) else {
return Err(ErrorOrException::Err(anyhow::anyhow!(
"data key not found in return object"
)));
};
let ret = cast!(
scope,
data_val,
v8::Uint8Array,
"bytes in the `data` field returned from `__call_view_anon__`"
)
.map_err(|e| e.throw(scope))?;
let bytes = ret.get_contents(&mut []);
Ok(ViewReturnData::HeaderFirst(Bytes::copy_from_slice(bytes)))
}
/// Calls the `__call_view_anon__` function `fun`.
pub(super) fn call_call_view_anon(View on GitHub (pinned to 524b4487d9)
Solutions
- Regenerate the JS bindings for the deployed host/ABI version and republish the module.
- Keep the returned envelope exactly `{ data: Uint8Array }` in any custom wrapper.
- Verify the deployed bundle actually contains the regenerated wrapper (bust caches).
- Pin host and bindings versions together in CI so they cannot drift.
Example fix
// before: v2 wrapper returns rows under a different key
return { rows: encoded };
// after: v2 envelope with the `data` field
return { data: encoded }; Defensive patterns
Strategy: validation
Validate before calling
// v2 envelope check in bindings tests
const out = await callViewAnon(viewId, args);
if (!(out && out.data instanceof Uint8Array)) {
throw new Error('v2 view call must return { data: Uint8Array }');
} Type guard
function isV2ViewEnvelope(v: unknown): v is { data: Uint8Array } {
return typeof v === 'object' && v !== null && (v as any).data instanceof Uint8Array;
} Prevention
- Pin host and bindings versions together in CI.
- Keep the returned envelope exactly { data: Uint8Array } in custom wrappers.
- Verify the deployed bundle contains the regenerated wrapper after upgrades.
When it happens
Trigger: The v2 view wrapper returns an object lacking `data`: bindings generated for a different ABI or host version than deployed, a custom override of __call_view_anon__ returning a different envelope, or mixed old/new bundle code after an upgrade.
Common situations: Upgrading the host without regenerating JS bindings; forking or wrapping generated view entry points; serving stale bundles from caches after a republish.
Related errors
- data key not found in return object
- default export is not a Schema object
- Math.random is not available in SpacetimeDB modules. Use ctx
- The encoding label provided is invalid
- Option 'ignoreBOM' not supported
AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16).
Data as JSON: /api/errors/4affd07c9b1c26e9.
Report an issue: GitHub.