{"record":{"id":"e1190ca5ba929617","repo":"BoundaryML/baml","slug":"ai-prompt-messages-receiver-must-be-an-ai-prompt-instance","errorCode":null,"errorMessage":"ai.Prompt.messages receiver must be an ai.Prompt instance","messagePattern":"ai\\.Prompt\\.messages receiver must be an ai\\.Prompt instance","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"baml_language/crates/bex_vm/src/package_baml/prompt.rs","lineNumber":329,"sourceCode":"            }\n        }\n    }\n}\n\nimpl BamlClassPrompt for PackageAiImpl {\n    fn text(vm: &BexVm, prompt: &ai_view::Prompt<'_>) -> bex_str::BexStr {\n        let data = prompt.instance.load_field(0);\n        let prompt = vm\n            .as_rust_data::<PromptAst>(&data)\n            .expect(\"ai.Prompt._data must contain baml_builtins2::PromptAst\");\n        bex_str::BexStr::from(prompt.render_text())\n    }\n\n    fn messages(vm: &mut BexVm, prompt: &Value) -> Vec<Value> {\n        let messages = {\n            let instance = vm\n                .as_instance(prompt)\n                .expect(\"ai.Prompt.messages receiver must be an ai.Prompt instance\");\n            let data = instance.load_field(0);\n            vm.as_rust_data::<PromptAst>(&data)\n                .expect(\"ai.Prompt._data must contain baml_builtins2::PromptAst\")\n                .to_structured_messages()\n        };\n        let message_class = vm.resolve_class(\"ai.PromptMessage\");\n        messages\n            .into_iter()\n            .map(|(role, content, metadata)| {\n                let role = Value::object(vm.alloc_string(role));\n                let readable = Value::object(vm.alloc_string(content.to_text()));\n                let parts = prompt_content_values(vm, content.as_ref());\n                let parts =\n                    Value::object(vm.alloc_array(bex_vm_types::RealizedTy::unknown(), parts));\n                let metadata = prompt_metadata_value(vm, metadata);\n                Value::object(\n                    vm.alloc_instance(message_class, vec![role, readable, parts, metadata]),\n                )","sourceCodeStart":311,"sourceCodeEnd":347,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/baml_language/crates/bex_vm/src/package_baml/prompt.rs#L311-L347","documentation":"Panic in `ai.Prompt.messages` when the receiver value is not an `ai.Prompt` instance at all. The method calls `vm.as_instance(prompt).expect(...)` before reading field 0, so any non-instance value passed as the method receiver aborts. This guards the implicit `self` contract of the Prompt class methods.","triggerScenarios":"Calling `ai.Prompt.messages` with a value that is not a class instance (a primitive, a map, a union value) — typically from custom glue code, reflection-based dispatch, or a dispatch bug that fails to bind the receiver.","commonSituations":"Embedding the VM and invoking Prompt methods manually with wrong receiver values; partially applied/curried native calls where the receiver argument was dropped.","solutions":["Ensure the receiver is a real ai.Prompt instance: check vm.as_instance(value).is_ok() before calling messages.","Invoke messages via normal BAML method-call syntax so the receiver is bound automatically.","Fix any custom dispatch code that drops or substitutes the receiver argument."],"exampleFix":"// before\nlet msgs = PackageAiImpl::messages(&mut vm, &maybe_prompt);\n// after\nif vm.as_instance(&maybe_prompt).is_err() {\n    return; // receiver is not an ai.Prompt instance\n}\nlet msgs = PackageAiImpl::messages(&mut vm, &maybe_prompt);","handlingStrategy":"type-guard","validationCode":"fn is_prompt_instance(vm: &BexVm, value: &Value) -> bool {\n    vm.as_instance(value).is_ok()\n}","typeGuard":"fn prompt_receiver<'a>(vm: &BexVm, v: &'a Value) -> Option<&'a Instance> {\n    vm.as_instance(v).ok()\n}","tryCatchPattern":"// Guard the receiver before the method call:\nif prompt_receiver(&vm, &value).is_none() { return; /* not an ai.Prompt */ }","preventionTips":["Invoke Prompt methods via normal BAML method-call syntax so the receiver binds automatically.","In embeddings, check as_instance before dispatching class methods.","Don't pass primitives or maps where an ai.Prompt receiver is expected."],"tags":["rust","prompt","receiver","panic"],"backgroundTag":"internal-invariant-violation","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}