BoundaryML/baml · error

generic media cannot inhabit a concrete prompt part

Error message

generic media cannot inhabit a concrete prompt part

What it means

This panic fires when the BAML VM tries to render a media value into a concrete prompt part but the media's kind is `Generic`. Generic media is a placeholder/type-level carrier that has no concrete prompt class (Image/Audio/Video/Pdf), so the VM treats its presence in a prompt as an unrecoverable compiler/VM invariant violation rather than a user error.

Solutions

  1. Ensure the media value is a concrete kind (Image/Audio/Video/Pdf) before inserting it into a prompt part; construct it via the corresponding media constructor.
  2. Check the static type of the field/expression feeding the prompt; if it is generic media, narrow or convert it explicitly.
  3. Report this to the BAML maintainers if a well-typed program hits it — it indicates a VM invariant leak.

Example fix

// before (generic media flowing into prompt)
prompt: media_value
// after
prompt: media_value as baml.media.Image  // ensure concrete media kind is used
Defensive patterns

Strategy: type-guard

Validate before calling

// before inserting media into a prompt
if media.kind == "Generic" { throw new Error("media must be a concrete kind (image/audio/video/pdf) before use in a prompt"); }

Type guard

function isConcreteMedia(m) { return m && m.kind !== undefined && ["Image","Audio","Video","Pdf"].includes(m.kind); }

Prevention

When it happens

Trigger: Calling prompt construction (prompt_content_values, reached via messages) with a value whose MediaKind is Generic — e.g. media produced by a generic-typed field or API path that did not specialize to image/audio/video/pdf before being placed into a prompt part.

Common situations: Assigning a generically-typed media (e.g. from a `media` union or dynamic input) directly into a prompt; a type-checking gap that let unspecialized media reach prompt rendering; wiring a media value read from external data without refining its kind.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/4460e68cfe109679. Report an issue: GitHub.

Appendix: source

Thrown at baml_language/crates/bex_vm/src/package_baml/prompt.rs:375

fn prompt_metadata_value(vm: &mut BexVm, metadata: serde_json::Value) -> Value {
    let metadata = match metadata {
        serde_json::Value::Object(_) => metadata,
        _ => serde_json::Value::Object(serde_json::Map::new()),
    };
    super::json::serde_to_value(vm, &metadata)
}

fn prompt_content_values(vm: &mut BexVm, content: &PromptAstSimple) -> Vec<Value> {
    match content {
        PromptAstSimple::String(text) => vec![Value::object(vm.alloc_string(text.clone()))],
        PromptAstSimple::Media(media) => {
            let class_name = match media.kind {
                baml_type::MediaKind::Image => "baml.media.Image",
                baml_type::MediaKind::Audio => "baml.media.Audio",
                baml_type::MediaKind::Video => "baml.media.Video",
                baml_type::MediaKind::Pdf => "baml.media.Pdf",
                baml_type::MediaKind::Generic => {
                    panic!("generic media cannot inhabit a concrete prompt part")
                }
            };
            let class = vm.resolve_class(class_name);
            let data = Value::object(vm.alloc_rust_data(media.clone()));
            vec![Value::object(vm.alloc_instance(class, vec![data]))]
        }
        PromptAstSimple::Multiple(parts) => parts
            .iter()
            .flat_map(|part| prompt_content_values(vm, part.as_ref()))
            .collect(),
    }
}

impl BamlNamespaceInternal for PackageAiImpl {
    fn assemble_prompt(vm: &mut BexVm, parts: &[Value], values: &[Value]) -> NativeCallResult {
        let mut pending = Vec::new();
        for value in values.iter().copied() {
            if prompt_role(vm, value).is_none()

View on GitHub (pinned to bd85ce9dee)