{"record":{"id":"72c89854d8353758","repo":"clockworklabs/SpacetimeDB","slug":"expected-moduledef-to-contain-key-but-it-does-not","errorCode":null,"errorMessage":"expected ModuleDef to contain key, but it does not","messagePattern":"expected ModuleDef to contain key, but it does not","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/schema/src/def.rs","lineNumber":571,"sourceCode":"\n    /// The `TableDef` an entity in the global namespace is stored in, if any.\n    ///\n    /// Generally, you will want to use the `lookup` method on the entity type instead.\n    pub fn stored_in_table_def(&self, name: &RawIdentifier) -> Option<&TableDef> {\n        self.stored_in_table_def\n            .get(name)\n            .and_then(|table_name| self.tables.get(table_name))\n    }\n\n    /// Lookup a definition by its key in `self`.\n    pub fn lookup<T: ModuleDefLookup>(&self, key: T::Key<'_>) -> Option<&T> {\n        T::lookup(self, key)\n    }\n\n    /// Lookup a definition by its key in `self`, panicking if not found.\n    /// Only use this method if you are sure the key exists in the module definition.\n    pub fn lookup_expect<T: ModuleDefLookup>(&self, key: T::Key<'_>) -> &T {\n        T::lookup(self, key).expect(\"expected ModuleDef to contain key, but it does not\")\n    }\n\n    /// Convenience method to look up a table, possibly by a string.\n    pub fn table<K: ?Sized + Hash + Equivalent<Identifier>>(&self, name: &K) -> Option<&TableDef> {\n        // If the string IS a valid identifier, we can just look it up.\n        self.tables.get(name)\n    }\n\n    /// Convenience method to look up a view, possibly by a string.\n    pub fn view<K: ?Sized + Hash + Equivalent<Identifier>>(&self, name: &K) -> Option<&ViewDef> {\n        // If the string IS a valid identifier, we can just look it up.\n        self.views.get(name)\n    }\n\n    /// Convenience method to look up a view, possibly by a string, returning its id as well.\n    pub fn view_full<K: ?Sized + Hash + Equivalent<Identifier>>(&self, name: &K) -> Option<(ViewFnPtr, &ViewDef)> {\n        // If the string IS a valid identifier, we can just look it up.\n        self.views.get(name).map(|def| (def.fn_ptr, def))","sourceCodeStart":553,"sourceCodeEnd":589,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/524b4487d949b61a07d4f39c862d1290259dfd20/crates/schema/src/def.rs#L553-L589","documentation":"`ModuleDef::lookup_expect` is the panicking variant of `lookup`: it resolves a table/view/reducer/index by key and `.expect`s the result, reserved for cases where presence is guaranteed by construction. It panics when the key is absent from the loaded module definition — wrong name, renamed entity, or an id from a stale module build.","triggerScenarios":"Calling lookup_expect(\"table_name\") or lookup_expect(table_id) with a key that doesn't exist in this ModuleDef — host code holding ids/names from an older module build, codegen referring to renamed entities, or programmatic lookups built from user input.","commonSituations":"Version skew between a module build and host caches/bindings; an entity renamed without regenerating bindings; user-supplied table names passed straight to lookup_expect; tests running against outdated fixture defs.","solutions":["Switch to the non-panicking `lookup(key)` and turn None into a proper error when presence is not statically guaranteed.","Regenerate bindings/ModuleDef artifacts so names and ids match the current published module.","Log the missing key alongside the set of known keys to spot renames and id drift quickly."],"exampleFix":"// before\nlet table = module_def.lookup_expect(\"players\");\n\n// after\nlet table = module_def.lookup(\"players\")\n    .ok_or_else(|| anyhow::anyhow!(\"table `players` not found in module\"))?;","handlingStrategy":"validation","validationCode":"if module_def.lookup(key).is_none() {\n    return Err(format!(\"key {:?} not found in module def\", key).into());\n}\nlet def = module_def.lookup_expect(key);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefer lookup() plus ok_or_else outside provably-invariant paths.","Regenerate bindings after module changes; assert expected entity names at startup.","Log the missing key with the known keys to catch renames and id drift."],"tags":["rust","spacetimedb","schema","moduledef","lookup"],"backgroundTag":"map-lookup-missing-key","analyzedSha":"524b4487d949b61a07d4f39c862d1290259dfd20","analyzedAt":"2026-08-16T23:58:54.611Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}