apache/iceberg · error
Could not build name to arg map
Error message
Could not build name to arg map: ${validationErrors.mkString(", ")} What it means
Thrown by ResolveProcedures when named CALL arguments fail validation: the same name is supplied twice ("Duplicate procedure argument: X") or a supplied name matches no procedure parameter ("Unknown argument: X"). All validation errors are aggregated into one message.
Solutions
- Fix the names listed in the message: remove duplicates and correct unknown argument names to match the procedure's parameter names
- List the procedure's parameters (catalog docs / DESCRIBE) and validate each named argument against them
- Convert to positional arguments if names are uncertain
Example fix
// before CALL catalog.system.expire_snapshots(table => 'db.t', table => 'db.t') // after CALL catalog.system.expire_snapshots(table => 'db.t')
Defensive patterns
Strategy: validation
Validate before calling
val names = namedArgs.map(_.name)
val unknown = names.filterNot(paramNames.contains)
val dupes = names.groupBy(identity).collect { case (n, l) if l.size > 1 => n }
require(unknown.isEmpty && dupes.isEmpty, s"unknown: $unknown, dupes: $dupes") Try / catch
try { spark.sql(callSql) } catch { case e: AnalysisException if e.getMessage.startsWith("Could not build name to arg map") => // fix names per message } Prevention
- Validate each named argument against the procedure's declared parameter names
- Avoid building CALL SQL by string concatenation that can repeat arguments
- Keep parameter names in sync when copying CALLs between procedures
When it happens
Trigger: CALL proc(a => 1, a => 2) (duplicate) or CALL proc(were => '...') (typo — name not in the procedure's parameter map).
Common situations: Typos in named arguments; pasting a CALL twice with an argument repeated; referencing parameters of a different procedure version whose names changed.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Missing required parameters
- Named and positional arguments cannot be mixed
- Cannot use catalog : not a ProcedureCatalog
- Too many arguments for procedure
- Wrong arg type for : cannot cast $argType to $paramType
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/111d82a3d289cb32.
Report an issue: GitHub.
Appendix: source
Thrown at spark/v3.5/spark-extensions/src/main/scala/org/apache/spark/sql/catalyst/analysis/ResolveProcedures.scala:145
buildNameToArgMapUsingNames(args, nameToPositionMap)
} else {
buildNameToArgMapUsingPositions(args, params)
}
}
private def buildNameToArgMapUsingNames(
args: Seq[CallArgument],
nameToPositionMap: Map[String, Int]): Map[String, CallArgument] = {
val namedArgs = args.asInstanceOf[Seq[NamedArgument]]
val validationErrors = namedArgs.groupBy(_.name).collect {
case (name, matchingArgs) if matchingArgs.size > 1 => s"Duplicate procedure argument: $name"
case (name, _) if !nameToPositionMap.contains(name) => s"Unknown argument: $name"
}
if (validationErrors.nonEmpty) {
throw new AnalysisException(
s"Could not build name to arg map: ${validationErrors.mkString(", ")}")
}
namedArgs.map(arg => arg.name -> arg).toMap
}
private def buildNameToArgMapUsingPositions(
args: Seq[CallArgument],
params: Seq[ProcedureParameter]): Map[String, CallArgument] = {
if (args.size > params.size) {
throw new AnalysisException("Too many arguments for procedure")
}
args.zipWithIndex.map { case (arg, position) =>
val param = params(position)
param.name -> arg
}.toMapView on GitHub (pinned to 86d9c8fc54)