clockworklabs/SpacetimeDB · error

data key not found in return object

Error message

data key not found in return object

What it means

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.

Source

Thrown at crates/core/src/host/v8/syscall/v1.rs:562

    // The original version returned a byte array with the encoded rows.
    if ret.is_typed_array() && ret.is_uint8_array() {
        // This is the original format, which just returns the raw bytes.
        let ret =
            cast!(scope, ret, v8::Uint8Array, "bytes return from `__call_view_anon__`").map_err(|e| e.throw(scope))?;
        let bytes = ret.get_contents(&mut []);

        return Ok(ViewReturnData::Rows(Bytes::copy_from_slice(bytes)));
    };

    // The newer version 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

  1. Align the JS bindings version with the host release: regenerate, rebuild, republish.
  2. If __call_view_anon__ is customized, return `{ data: new Uint8Array(...) }` or a plain Uint8Array for the legacy path.
  3. If returning an error object, use the documented error channel instead of a missing-data envelope.
  4. Reproduce with a minimal anonymous view on the matching host version.

Example fix

// before: custom wrapper returns an object without `data`
globalThis.__call_view_anon__ = () => ({ rows: bytes });

// after: include the `data` field the host reads
globalThis.__call_view_anon__ = () => ({ data: bytes });
Defensive patterns

Strategy: validation

Validate before calling

// bindings test: the anon-view wrapper must return the documented envelope
const out = await callViewAnon(viewId, args);
const ok = out instanceof Uint8Array
    || (typeof out === 'object' && out !== null && out.data instanceof Uint8Array);
if (!ok) throw new Error('view wrapper must return bytes or { data: Uint8Array }');

Type guard

function isViewEnvelope(v: unknown): v is Uint8Array | { data: Uint8Array } {
  return v instanceof Uint8Array
      || (typeof v === 'object' && v !== null && (v as any).data instanceof Uint8Array);
}

Prevention

When it happens

Trigger: __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.

Common situations: 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.

Related errors


AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16). Data as JSON: /api/errors/65ecc410c98ebaa3. Report an issue: GitHub.