apache/iceberg · error · AnalysisException
Wrong arg type for : cannot cast $argType to $paramType
Error message
Wrong arg type for ${param.name}: cannot cast $argType to $paramType What it means
Thrown by ProcedureArgumentCoercion when a CALL argument's data type cannot be safely up-cast to the corresponding procedure parameter's type. Iceberg only allows implicit upcasts (via Cast.canUpCast); anything else fails analysis.
Solutions
- Add an explicit CAST to the parameter's type in the CALL, e.g. CAST('2024-01-01' AS TIMESTAMP)
- Check the procedure signature and reorder arguments so each value's type upcasts to the parameter type
- Use a typed literal (e.g. TIMESTAMP '2024-01-01', 5L) instead of an untyped literal
Example fix
// before
CALL catalog.system.rewrite_data_files(table => 'db.t', where => 'ts > 2024-01-01')
// after
CALL catalog.system.rewrite_data_files(table => 'db.t', where => cast('ts > ''2024-01-01''' as string)) Defensive patterns
Strategy: validation
Validate before calling
// before CALL, ensure each literal's type upcasts: // e.g. for a TIMESTAMP param use TIMESTAMP '2024-01-01', for LONG use 5L val argType = expr.exprType require(Cast.canUpCast(argType, paramType), s"cannot cast $argType to $paramType")
Try / catch
try { spark.sql(callSql) } catch { case e: AnalysisException if e.getMessage.contains("Wrong arg type for") => // add explicit CAST } Prevention
- Use typed literals (TIMESTAMP '...', 5L, DATE '...') for typed procedure parameters
- Match argument order to the declared parameter order
- Check the procedure signature docs before calling
When it happens
Trigger: CALL catalog.system.procedure(arg) where e.g. an INT argument targets a STRING parameter, or a DOUBLE targets an INT parameter — no lossless upcast exists.
Common situations: Passing string literals for typed parameters (timestamps, longs); calling procedures ported across Spark versions where default literal types changed (e.g. DECIMAL vs DOUBLE literals); mismatched parameter order so the value lands on the wrong typed parameter.
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
- Cannot use catalog : not a ProcedureCatalog
- Could not build name to arg map
- Missing required parameters
- Named and positional arguments cannot be mixed
- Too many arguments for procedure
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/27250e7359549146.
Report an issue: GitHub.
Appendix: source
Thrown at spark/v3.5/spark-extensions/src/main/scala/org/apache/spark/sql/catalyst/analysis/ProcedureArgumentCoercion.scala:38
import org.apache.spark.sql.AnalysisException
import org.apache.spark.sql.catalyst.expressions.Cast
import org.apache.spark.sql.catalyst.plans.logical.Call
import org.apache.spark.sql.catalyst.plans.logical.LogicalPlan
import org.apache.spark.sql.catalyst.rules.Rule
object ProcedureArgumentCoercion extends Rule[LogicalPlan] {
override def apply(plan: LogicalPlan): LogicalPlan = plan resolveOperators {
case c @ Call(procedure, args) if c.resolved =>
val params = procedure.parameters
val newArgs = args.zipWithIndex.map { case (arg, index) =>
val param = params(index)
val paramType = param.dataType
val argType = arg.dataType
if (paramType != argType && !Cast.canUpCast(argType, paramType)) {
throw new AnalysisException(
s"Wrong arg type for ${param.name}: cannot cast $argType to $paramType")
}
if (paramType != argType) {
Cast(arg, paramType)
} else {
arg
}
}
if (newArgs != args) {
c.copy(args = newArgs)
} else {
c
}
}
}
View on GitHub (pinned to 86d9c8fc54)