Skip to content

Say what a type mismatch expected and what it got - #122

Merged
walterxie merged 1 commit into
masterfrom
fix/type-mismatch-error-message
Jul 24, 2026
Merged

Say what a type mismatch expected and what it got#122
walterxie merged 1 commit into
masterfrom
fix/type-mismatch-error-message

Conversation

@alexeid

@alexeid alexeid commented Jul 24, 2026

Copy link
Copy Markdown
Member

Problem

A type mismatch reports only the input name:

Input 102b: type mismatch for input mean

It names neither the expected nor the supplied type. The XMLParserException that wraps it prints an "Error detected about here" path built from the enclosing element, not the offending child — setInput is handed the parent node and the child never reaches the message — so the reported location is only ever approximate. In practice, finding the cause means opening the source of whichever class declares the input.

This is worst during migration. A legacy BEAST 2 class and its BEAST 3 spec twin usually share a simple name, and in XML a bare element name silently resolves to the legacy class:

<Exponential name="distr">   <!-- beast.base.inference.distribution.Exponential -->

That is an easy mistake to make and a slow one to find — it cost a round trip on BEAST2-Dev/bModelTest#7, where the same message appeared with no indication that legacy-vs-spec was the issue.

Change

Report the input, the object carrying it, the expected type with its domain, and the supplied type. When the supplied class is a legacy beast.base class where a beast.base.spec one is wanted, say so explicitly and show the spec= form.

Before:

Input 102b: type mismatch for input mean

After:

Input 102b: type mismatch for input 'mean' of beast.base.spec.inference.distribution.Exponential id='post'
  expected: beast.base.spec.type.RealScalar with domain beast.base.spec.domain.PositiveReal
  but got:  beast.base.inference.parameter.RealParameter

beast.base.inference.parameter.RealParameter is a legacy BEAST 2 class, but this input expects a BEAST 3 spec class.
In XML this usually means a bare element name was used, as in <RealParameter name='mean'>, which resolves to the legacy
class. Name the input and give it an explicit spec instead, as in <mean spec='beast.base.spec...'>.

Scope is deliberately narrow: only the 102b branch, which carried no type information at all. Error 101 already reports both types and XMLParser special-cases it, so it is left alone to avoid duplicated text.

Tests

InputTypeMismatchMessageTest covers the four cases: the message names input, owner, expected and actual; a legacy class gets the migration hint; a spec-vs-spec mismatch (vector where a scalar is wanted) does not get a misleading hint; and a correctly typed parameter is still accepted.

Full beast-base suite: 462 tests, 0 failures.

Not addressed

The "Error detected about here" location still points at the enclosing element. Fixing that means threading the child Node through NameValuePair into setInput, which is a larger change — happy to do it separately if wanted.

The message was just 'Input 102b: type mismatch for input mean'. It named
neither the expected nor the supplied type, and the XML parser error that
wraps it points at the enclosing element rather than the offending child,
so the reported location is only ever approximate. Working out what was
wrong meant reading the source of the class declaring the input.

This is worst during migration, because a legacy BEAST 2 class and its
BEAST 3 spec twin usually share a simple name and are indistinguishable
in the message. In XML a bare element name silently resolves to the
legacy class, which is an easy mistake to make and a slow one to find --
it cost us a round trip on BEAST2-Dev/bModelTest#7.

Report the input, the object carrying it, the expected type with its
domain, and the supplied type; and when the supplied class is a legacy
beast.base class where a beast.base.spec one is wanted, say so and show
the explicit spec= form. Before:

    Input 102b: type mismatch for input mean

after:

    Input 102b: type mismatch for input 'mean' of
    beast.base.spec.inference.distribution.Exponential id='post'
      expected: beast.base.spec.type.RealScalar with domain beast.base.spec.domain.PositiveReal
      but got:  beast.base.inference.parameter.RealParameter

    beast.base.inference.parameter.RealParameter is a legacy BEAST 2 class,
    but this input expects a BEAST 3 spec class. In XML this usually means a
    bare element name was used, as in <RealParameter name='mean'>, which
    resolves to the legacy class. Name the input and give it an explicit spec
    instead, as in <mean spec='beast.base.spec...'>.

beast-base suite: 462 tests, 0 failures.
@alexeid
alexeid requested a review from walterxie July 24, 2026 01:28
@walterxie
walterxie merged commit 862bd9e into master Jul 24, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants