{"record":{"id":"e96e44497a01cc1a","repo":"wasmerio/wasmer","slug":"ref-is-null-only-accepts-reference-types","errorCode":null,"errorMessage":"ref.is_null only accepts reference types","messagePattern":"ref\\.is_null only accepts reference types","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/compiler-llvm/src/translator/code.rs","lineNumber":11415,"sourceCode":"        match op {\n            Operator::RefNull { hty } => {\n                let ty = err!(wpheaptype_to_type(hty));\n                let ty = type_to_llvm(self.intrinsics, ty)?;\n                self.state.push1(ty.const_zero());\n            }\n            Operator::RefIsNull => {\n                let value = self.state.pop1()?;\n                let is_null = match value {\n                    BasicValueEnum::IntValue(value) => err!(self.builder.build_int_compare(\n                        IntPredicate::EQ,\n                        value,\n                        value.get_type().const_zero(),\n                        \"\",\n                    )),\n                    BasicValueEnum::PointerValue(value) => {\n                        err!(self.builder.build_is_null(value, \"\"))\n                    }\n                    _ => unreachable!(\"ref.is_null only accepts reference types\"),\n                };\n                let is_null = err!(self.builder.build_int_z_extend(\n                    is_null,\n                    self.intrinsics.i32_ty,\n                    \"\"\n                ));\n                self.state.push1(is_null);\n            }\n            Operator::RefFunc { function_index } => {\n                let index = self\n                    .intrinsics\n                    .i32_ty\n                    .const_int(function_index.into(), false);\n                let value = self\n                    .build_call_with_param_attributes(\n                        self.intrinsics.func_ref,\n                        &[self.ctx.basic().into(), index.into()],\n                        \"\",","sourceCodeStart":11397,"sourceCodeEnd":11433,"githubUrl":"https://github.com/wasmerio/wasmer/blob/8c4b9ee9d33fb2068863fbb3d328683e7e6ff7f5/lib/compiler-llvm/src/translator/code.rs#L11397-L11433","documentation":"`unreachable!(\"ref.is_null only accepts reference types\")` fires in translate_reference_operator when the value pushed for a RefIsNull operand is neither a FuncValue/externref-style reference, pointer, nor typed-reference value the backend recognizes. The translator's internal value representation didn't match any expected reference-kind LLVM value.","triggerScenarios":"RefIsNull applied to a value whose translated LLVM type is not a reference (funcref/externref) — e.g. after a canonicalization bug, a mis-validated module feeding a non-ref operand, or enum/type-representation changes between wasmparser and the translator.","commonSituations":"Modules that skip validation (custom loaders, AOT pipelines feeding raw sections); wasmparser version skew changing how heap types are represented; hand-crafted wasm.","solutions":["Always run the module through wasmparser::Validator (or wasmer::Module::validate) before compilation so RefIsNull operands are guaranteed refs","Upgrade wasmer to keep the value-representation in sync with wasmparser","Check the producing function's return type is funcref/externref, not i32 faked as a ref","Patch the arm to return a CompileError instead of unreachable! if maintaining a fork"],"exampleFix":"// before\nModule::new(&store, unvalidated_bytes); // bad ref operand reaches backend\n// after\nwasmparser::Validator::new_with_features(features).validate_all(&bytes)?;\nModule::new(&store, bytes)?;","handlingStrategy":"validation","validationCode":"wasmparser::Validator::new_with_features(WasmFeatures {\n    reference_types: true, ..Default::default()\n}).validate_all(&bytes)?; // guarantees ref.is_null operands are reference types","typeGuard":"fn is_reference_type(t: &wasmparser::HeapType) -> bool {\n    matches!(t.composite_type(), None) || matches!(t, wasmparser::HeapType::Func | wasmparser::HeapType::Extern | wasmparser::HeapType::Any)\n}","tryCatchPattern":null,"preventionTips":["Always validate modules — never feed raw sections directly to AOT","Ensure ref.is_null operands are typed funcref/externref, not integers","Track wasmparser heap-type representation changes when upgrading"],"tags":["rust","unreachable","wasm","reference-types"],"backgroundTag":"ref-is-null-invalid-type","analyzedSha":"8c4b9ee9d33fb2068863fbb3d328683e7e6ff7f5","analyzedAt":"2026-09-01T23:06:31.009Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}