My first guess on this would be that there's an interaction between type checking on templates and tail call optimization. Your first template has a tail call to apply-templates, which would normally be optimised (on the assumption that it's potentially a recursive call); the tail call optimization should be suppressed if type checking of the result is required. However, I've tried to put together a little stylesheet {my ref schema090} that has all the features of yours, and I can't reproduce the failure.
You could test whether my theory is correct by adding
<xsl:sequence select="$nothing"/>
after the call on apply-templates, where $nothing is defined as
<xsl:param name="nothing" select="()"/>
This should suppress the tail-call optimisation.
Is it possible to cut down the example to something I can reproduce? (I know this is always difficult with schemas).
Michael Kay

From: [] On Behalf Of Alan Painter
Sent: 06 June 2005 16:55
Subject: [saxon] Funny typing error

With SaxonSA 8.4, I'm running into a funny runtime type-checking problem.

I have a template in mode "A" with match="inType", as="outType".
In this simple test, the template "A" doesn't do anything except
apply-templates, selecting "current()" with mode = "B".

The template in mode "B" has the same "as" and "match"
attributes as "A" and it creates an "element" of the required type.

The funny thing is that I'm running into an error when the template in mode "A"
is matched and it does an "appy-templates" in mode "B".  The "return" type
of the template in mode "B" seems to get lost, becoming "xdt:untyped", although it
seems to hold onto the name of the element that was generated.

Error on line ...
  XP0006: Required type of result of template
  match="element(*,defiml:DL_LoanOrFacilityParty)" is element(*, ApporteurAffaireType);
  supplied value has type element(ApporteurAffaire, xdt:untyped)

If I go into mode "B" directly with out the indirection by the template in mode "A", I don't run into this error.

Any ideas on this one?

    <!-- ================================= -->
    <!-- ApporteurAffaireChoice: (667) -->
    <!-- ================================= -->
    <xsl:template match="element(*,defiml:DL_LoanOrFacilityParty)" as="element(*, fsc2:ApporteurAffaireType)" mode="ApporteurAffaireChoice" >
        <xsl:param name="elementName" as="xs:string" required="yes" />
        <xsl:apply-templates select="current()" mode="ApporteurAffaireS" >
            <xsl:with-param name="elementName" select="'ApporteurAffaire'" as="xs:string"/>
    <!-- ================================= -->
    <!-- ApporteurAffaireS: (677) -->
    <!-- ================================= -->
    <xsl:template match="element(*,defiml:DL_LoanOrFacilityParty)" as="element(*, fsc2:ApporteurAffaireType)" mode="ApporteurAffaireS" >
        <xsl:param name="elementName" as="xs:string" required="yes" />
        <xsl:element name="{$elementName}" type="fsc2:ApporteurAffaireType" >
            <xsl:if test="exists(transco:ReferentielsClient('NumCliElemBDR'))" >
                <xsl:attribute name="referClients" select="transco:ReferentielsClient('NumCliElemBDR')" />
            <xsl:if test="exists(brkfct:getCompleteChain(brkfct:getPartyId(brkfct:getParty(partyReference)),10))" >
                <xsl:attribute name="code" select="brkfct:getCompleteChain(brkfct:getPartyId(brkfct:getParty(partyReference)),10)" />
            <xsl:if test="exists(brkfct:getStandardRate(partyRoleRate))" >
                <xsl:attribute name="pourApport" select="brkfct:getStandardRate(partyRoleRate)" />

Any suggestions appreciated.