{"record":{"id":"65ecc410c98ebaa3","repo":"clockworklabs/SpacetimeDB","slug":"data-key-not-found-in-return-object","errorCode":null,"errorMessage":"data key not found in return object","messagePattern":"data key not found in return object","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/core/src/host/v8/syscall/v1.rs","lineNumber":562,"sourceCode":"\n    // The original version returned a byte array with the encoded rows.\n    if ret.is_typed_array() && ret.is_uint8_array() {\n        // This is the original format, which just returns the raw bytes.\n        let ret =\n            cast!(scope, ret, v8::Uint8Array, \"bytes return from `__call_view_anon__`\").map_err(|e| e.throw(scope))?;\n        let bytes = ret.get_contents(&mut []);\n\n        return Ok(ViewReturnData::Rows(Bytes::copy_from_slice(bytes)));\n    };\n\n    // The newer version returns an object with a `data` field containing the bytes.\n    let ret = cast!(scope, ret, v8::Object, \"object return from `__call_view_anon__`\").map_err(|e| e.throw(scope))?;\n\n    let Some(data_key) = v8::String::new(scope, \"data\") else {\n        return Err(ErrorOrException::Err(anyhow::anyhow!(\"error creating a v8 string\")));\n    };\n    let Some(data_val) = ret.get(scope, data_key.into()) else {\n        return Err(ErrorOrException::Err(anyhow::anyhow!(\n            \"data key not found in return object\"\n        )));\n    };\n\n    let ret = cast!(\n        scope,\n        data_val,\n        v8::Uint8Array,\n        \"bytes in the `data` field returned from `__call_view_anon__`\"\n    )\n    .map_err(|e| e.throw(scope))?;\n    let bytes = ret.get_contents(&mut []);\n\n    Ok(ViewReturnData::HeaderFirst(Bytes::copy_from_slice(bytes)))\n}\n\n/// Calls the `__call_view_anon__` function `fun`.\npub(super) fn call_call_view_anon(","sourceCodeStart":544,"sourceCodeEnd":580,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/524b4487d949b61a07d4f39c862d1290259dfd20/crates/core/src/host/v8/syscall/v1.rs#L544-L580","documentation":"For ABI-v1 anonymous view calls, the host invokes the module's __call_view_anon__ and accepts either a raw Uint8Array (legacy fast path) or an object whose `data` field holds the bytes. This error fires on the object path when reading the `data` property fails: the return is an object but has no retrievable `data` key. The module's JS bindings and the host disagree on the return envelope.","triggerScenarios":"__call_view_anon__ returns an object lacking `data`: a bindings/host version mismatch where the wrapper returns a different envelope (for example an error object or a newer shape), or user code overriding __call_view_anon__ and returning a custom object.","commonSituations":"JS module built with bindings older or newer than the host's supported envelope; monkey-patching or wrapping the generated view entry points; partial bundle updates after a host upgrade.","solutions":["Align the JS bindings version with the host release: regenerate, rebuild, republish.","If __call_view_anon__ is customized, return `{ data: new Uint8Array(...) }` or a plain Uint8Array for the legacy path.","If returning an error object, use the documented error channel instead of a missing-data envelope.","Reproduce with a minimal anonymous view on the matching host version."],"exampleFix":"// before: custom wrapper returns an object without `data`\nglobalThis.__call_view_anon__ = () => ({ rows: bytes });\n\n// after: include the `data` field the host reads\nglobalThis.__call_view_anon__ = () => ({ data: bytes });","handlingStrategy":"validation","validationCode":"// bindings test: the anon-view wrapper must return the documented envelope\nconst out = await callViewAnon(viewId, args);\nconst ok = out instanceof Uint8Array\n    || (typeof out === 'object' && out !== null && out.data instanceof Uint8Array);\nif (!ok) throw new Error('view wrapper must return bytes or { data: Uint8Array }');","typeGuard":"function isViewEnvelope(v: unknown): v is Uint8Array | { data: Uint8Array } {\n  return v instanceof Uint8Array\n      || (typeof v === 'object' && v !== null && (v as any).data instanceof Uint8Array);\n}","tryCatchPattern":null,"preventionTips":["Regenerate and reinstall JS bindings on every host upgrade.","Do not override or wrap the generated __call_view_anon__ entry points.","Add a CI check for the view-call envelope shape."],"tags":["v8","views","anonymous-view","bindings-mismatch"],"backgroundTag":"response-shape-mismatch","analyzedSha":"524b4487d949b61a07d4f39c862d1290259dfd20","analyzedAt":"2026-08-16T23:58:54.611Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}