BoundaryML/baml · error

PlainDate.to_plain_datetime: expected PlainDate instance

Error message

PlainDate.to_plain_datetime: expected PlainDate instance

What it means

Panic in PlainDate.to_plain_datetime: the receiver value is not a PlainDate instance, so extracting its internal days field fails. The method's receiver must always be a PlainDate instance per the time library's invariants.

Solutions

  1. Verify the receiver is constructed via PlainDate constructor APIs before calling to_plain_datetime.
  2. If you have a PlainDateTime, use its appropriate conversion method instead.
  3. Add a type check on the value before the call.

Example fix

// before
let dt = plaindatetime.to_plain_datetime(t)
// after
let dt = plaindate.to_plain_datetime(t)  // ensure receiver is a PlainDate
Defensive patterns

Strategy: type-guard

Validate before calling

// before the call
if (typeof value.className !== 'undefined' && value.className !== 'PlainDate') throw new Error('receiver must be a PlainDate');

Type guard

function isPlainDate(v) { return v != null && v.className === 'PlainDate'; }

Prevention

When it happens

Trigger: Calling to_plain_datetime with a receiver value that is not a PlainDate instance — e.g. passing a PlainDateTime, a raw value, or an object of the wrong class.

Common situations: Mixing up PlainDate and PlainDateTime/PlainTime values; passing stored values of the wrong type recovered from dynamic data; calling internal methods on wrongly-typed receivers.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at baml_language/crates/bex_vm/src/package_baml/time.rs:227

            _days: days_since_epoch(date),
        };
        Ok(plaindate.to_value(vm))
    }

    fn _to_string_impl(
        plaindate: &view::time::PlainDate<'_>,
    ) -> Result<bex_str::BexStr, VmRustFnError> {
        let date = date_for_days(plaindate._days(), "PlainDate.to_string")?;
        let mut out = String::new();
        format_date_into(&mut out, date);
        Ok(bex_str::BexStr::from(out))
    }

    fn _to_plain_datetime(vm: &mut BexVm, plaindate: &Value, time_ns: i64) -> Value {
        let days = {
            let instance = vm
                .as_instance(plaindate)
                .expect("PlainDate.to_plain_datetime: expected PlainDate instance");
            view::time::PlainDate { instance }._days()
        };
        let civil = i128::from(days) * NANOS_PER_DAY + i128::from(time_ns);
        let plaindatetime = copy::time::PlainDateTime {
            _nanoseconds: Arc::new(num_bigint::BigInt::from(civil)),
        };
        plaindatetime.to_value(vm)
    }

    fn year(plaindate: &view::time::PlainDate<'_>) -> Result<i64, VmRustFnError> {
        Ok(i64::from(
            date_for_days(plaindate._days(), "PlainDate.year")?.year(),
        ))
    }

    fn month(plaindate: &view::time::PlainDate<'_>) -> Result<i64, VmRustFnError> {
        Ok(i64::from(u8::from(
            date_for_days(plaindate._days(), "PlainDate.month")?.month(),

View on GitHub (pinned to bd85ce9dee)