clockworklabs/SpacetimeDB · critical
unsupported type for :sender: {ty:?}
Error message
unsupported type for :sender: {ty:?} What it means
When executing a physical plan, ExecutionParams::resolve_param binds implicit parameter slots: PARAM_SENDER can bind only to parameters declared as Identity or as bytes (sender passed as big-endian bytes); the view-arg-hash slots only to U256; any unknown slot panics too. If the module's declared type for the :sender slot is anything else, resolve_param panics with the offending AlgebraicType. This is a module-ABI constraint: the caller identity can only be supplied to Identity- or bytes-typed parameters.
Source
Thrown at crates/execution/src/lib.rs:47
pub fn from_sender(sender: Identity) -> Self {
Self {
sender,
empty_view_arg_hash: hash_empty_view_args().to_u256(),
sender_view_arg_hash: hash_sender_view_args(sender).to_u256(),
}
}
pub fn from_auth(auth: &AuthCtx) -> Self {
Self::from_sender(auth.caller())
}
}
impl ParamResolver for ExecutionParams {
fn resolve_param(&self, param: ParamSlot, ty: &AlgebraicType) -> AlgebraicValue {
match param {
PARAM_SENDER if ty.is_identity() => self.sender.into(),
PARAM_SENDER if ty.is_bytes() => AlgebraicValue::Bytes(self.sender.to_be_byte_array().into()),
PARAM_SENDER => panic!("unsupported type for :sender: {ty:?}"),
PARAM_VIEW_ARG_HASH_EMPTY if matches!(ty, AlgebraicType::U256) => {
AlgebraicValue::U256(self.empty_view_arg_hash.into())
}
PARAM_VIEW_ARG_HASH_EMPTY => panic!("unsupported type for empty view arg hash: {ty:?}"),
PARAM_VIEW_ARG_HASH_SENDER if matches!(ty, AlgebraicType::U256) => {
AlgebraicValue::U256(self.sender_view_arg_hash.into())
}
PARAM_VIEW_ARG_HASH_SENDER => panic!("unsupported type for sender view arg hash: {ty:?}"),
ParamSlot(slot) => panic!("unknown physical plan parameter slot: {slot}"),
}
}
}
pub trait Datastore {
/// Iterator type for table scans
type TableIter<'a>: Iterator<Item = RowRef<'a>> + 'a
where
Self: 'a;View on GitHub (pinned to 6dee26c6ef)
Solutions
- Rebuild and republish the module with an SDK matching the server so the sender parameter is typed Identity.
- In module code, use ctx.sender (ReducerContext) or declare the parameter as Identity, not Address/String/custom types.
- If a bytes parameter is acceptable, declare it bytes and convert from the identity's big-endian byte array in module code.
Example fix
// before (older SDK ABI): sender parameter declared as Address
#[reducer]
fn tick(ctx: &ReducerContext, sender: Address) { /* ... */ }
// after: read the caller from the context as Identity
#[reducer]
fn tick(ctx: &ReducerContext) {
let sender: Identity = ctx.sender;
/* ... */
} Defensive patterns
Strategy: type-guard
Validate before calling
// before publishing, verify the sender slot's declared type
// (adapt to however you introspect the module; the host allows only these two)
fn sender_type_supported(ty: &AlgebraicType) -> bool {
ty.is_identity() || ty.is_bytes()
}
// in your build/publish checks: reject modules whose sender param fails this predicate Type guard
fn sender_type_supported(ty: &AlgebraicType) -> bool { ty.is_identity() || ty.is_bytes() } Prevention
- Prefer ctx.sender on ReducerContext over a dedicated sender parameter.
- Regenerate module bindings whenever the server or SDK version changes.
- Pin SDK and server versions together and verify with a staging publish after upgrades.
When it happens
Trigger: Executing a plan whose :sender implicit parameter is declared with a non-Identity, non-bytes type — typically a module compiled with an SDK whose caller parameter used a different type (e.g. Address), resolved when the plan binds PARAM_SENDER.
Common situations: SDK/server version skew across releases that changed the sender representation; hand-written wasm declaring the sender param as String or a custom type; porting modules between breaking ABI versions.
Related errors
- reducer ran out of energy
- cannot deserialize refs without a typespace
- There is already a reducer, procedure, or view with the name
- Table ${tableName} defines a schedule, but it seems like the
- Table ${tableName} defines multiple schedules: ${existingFun
AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20).
Data as JSON: /api/errors/233b8435fa7540b7.
Report an issue: GitHub.