You haven't shown your XML. If it's like this:
<a>
<b>
<c/>
</b>
</a>
and your template rules are
<xsl:template match="a">
<xsl:apply-templates>
<xsl:with-param name="x">23</xsl:with-param>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="c">
<xsl:param name="x".../>
</xsl:template>
then the apply-templates call selects the b element, there is no template rule for the b element, so the built-in template rule is invoked, this applies-templates to the c element, but without passing the parameters on. The solution is to add a template rule
<xsl:template match="b">
<xsl:param name="x"/>
<xsl:apply-templates>
<xsl:with-param name="x" select="$x"/>
</xsl:apply-templates>
</xsl:template>
or to make the call direct:
<xsl:template match="a">
<xsl:apply-templates select="b/c">
<xsl:with-param name="x">23</xsl:with-param>
</xsl:apply-templates>
</xsl:template>
>Why doesn't XSLT 1.0 pass the parameter by default?
Probably an oversight by the language designers. W3C did things a lot more quickly in those days and there wasn't so much time for review. XSLT 2.0 fixes many such usability problems.
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer's Reference