{"record":{"id":"58f7f4ae756c0c05","repo":"clockworklabs/SpacetimeDB","slug":"error-resolving-row-type-for-view","errorCode":null,"errorMessage":"Error resolving row type for view","messagePattern":"Error resolving row type for view","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/core/src/host/wasm_common/module_host_actor.rs","lineNumber":1486,"sourceCode":"            }\n            // TODO: maybe do something else with user errors?\n            (Err(ExecutionError::User(err)), _) => {\n                inst.log_traceback(\"view\", &view_name, &anyhow::anyhow!(err));\n                self.handle_outer_error(&result.stats.energy, &view_name).into()\n            }\n            (Ok(raw), sender) => {\n                // This is wrapped in a closure to simplify error handling.\n                let outcome: Result<ViewOutcome, anyhow::Error> = (|| {\n                    let view_call = match sender {\n                        Some(sender) => ViewCallInfo::sender(view_id, sender),\n                        None => ViewCallInfo::anonymous(view_id),\n                    };\n                    let result = ViewResult::from_return_data(raw).context(\"Error parsing view result\")?;\n                    let row_product_type = view_typespace\n                        .resolve(row_type)\n                        .resolve_refs()?\n                        .into_product()\n                        .map_err(|_| anyhow!(\"Error resolving row type for view\"))?;\n\n                    let rows = match result {\n                        ViewResult::Rows(bytes) => deserialize_view_rows(row_type, bytes, &view_typespace)\n                            .context(\"Error deserializing rows returned by view\".to_string())?,\n                        ViewResult::RawSql(query) => self\n                            .run_query_for_view(&mut tx, &query, &row_product_type, &view_call)\n                            .context(\"Error executing raw SQL returned by view\".to_string())?,\n                    };\n\n                    let replica_ctx = inst.replica_ctx();\n                    let stdb = replica_ctx.relational_db();\n                    stdb.materialize_view_call(&mut tx, table_id, view_call, rows)\n                        .context(\"Error materializing view\")?;\n\n                    Ok(ViewOutcome::Success)\n                })();\n                match outcome {\n                    Ok(outcome) => outcome,","sourceCodeStart":1468,"sourceCodeEnd":1504,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/eddf9f5014579a50d4b67630e28b6e15cad9c4af/crates/core/src/host/wasm_common/module_host_actor.rs#L1468-L1504","documentation":"Thrown while materializing the result of a one-off view call on the module host actor. The view's declared row type (row_type / product_type_ref from the module's BSATN typespace) either fails to resolve_refs() against the typespace or resolves to a type that is not a product (struct/row) type, so into_product() fails. In practice the module's type metadata and the view's declared return type disagree, which normally means a stale module definition is being used against mismatched module metadata.","triggerScenarios":"Calling view evaluation on the module host actor where view_typespace.resolve(row_type).resolve_refs() errors, or the resolved AlgebraicType is not a product type - e.g. the view's return type was changed to an enum/sum type or a scalar, or the host holds a module definition from a different build than the one that registered the view.","commonSituations":"Publishing an updated module that changed a view's return type while old metadata is still in play; hand-built or corrupted modules with invalid BSATN bindings; version skew between host and module SDK.","solutions":["Republish the module so database metadata, st_view rows, and the module definition all come from the same build","Verify every view's declared row type is a product (row/struct) type, not an enum or scalar","If it reproduces after a clean republish, minimize the module and report it as a SpacetimeDB issue"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before invoking view calls, verify the declared row type resolves to a product type\nfn view_row_type_is_product(ts: &Typespace, row_type: AlgebraicTypeRef) -> bool {\n    ts.resolve(row_type)\n        .resolve_refs()\n        .ok()\n        .and_then(|ty| ty.into_product().ok())\n        .is_some()\n}\n\nif !view_row_type_is_product(&typespace, view.product_type_ref) {\n    return Err(anyhow::anyhow!(\"view {} row type does not resolve to a product; republish the module\", view.name));\n}","typeGuard":null,"tryCatchPattern":"match call_view_result {\n    Err(e) if e.to_string().contains(\"Error resolving row type for view\") => {\n        // Surface an actionable message: republish module, check view return type\n    }\n    other => other,\n}","preventionTips":["Always publish modules built by the matching SDK version as the host","Keep view return types as row/product (struct) types, never enums or scalars","Run a smoke view call after each publish to catch type-metadata mismatches early"],"tags":["spacetimedb","views","bsatn","typespace","module-host"],"backgroundTag":"view-row-type-resolution-failed","analyzedSha":"eddf9f5014579a50d4b67630e28b6e15cad9c4af","analyzedAt":"2026-08-20T06:08:37.179Z","contentChangedAt":"2026-08-20T06:08:37.179Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}