Skip to content

[JENKINS-62680] Groovy withIndex function doesn't work normally in pipeline #224

Description

@jenkins-infra-bot

Note:

While this problem can be VERY confusing to diagnose depending on the situation, it does have a very reasonable workaround:
Instead of doing:
jsonArray.withIndex().each{Object str, Integer index -> currentBuild.echo("${idx.toString()} : ${str}")}
We can do:
jsonArray.withIndex().each{Tuple2 tuple2 -> currentBuild.echo("${tuple2.first} : ${tuple2.second}")}


Groovy adds withIndex() method to iterables which turns each element into a Tuple2 of Element + index.  When using any of the groovy collection methods following withIndex(), Groovy then typically deconstructs the Tuple2 in the closure, but that doesn't seem to happen when using withIndex() on Jenkins. 

The outputs below demonstrate the issue pretty clearly.  
 

// Run this in a Jenkins step

String jsonStr = "['zero', 'one', 'two']"
JSONArray jsonArray = new JsonSlurper().parseText(jsonStr) as JSONArray
jsonArray.withIndex().each{Object str, Integer idx -> currentBuild.echo("${idx.toString()} : ${str}")}
// OUTPUT from jenkins
// [Pipeline] echo
// null : [zero, 0]
// [Pipeline] echo
// null : [one, 1]
// [Pipeline] echo
// null : [two, 2]

// Run this locally in a groovy file or unit test

String jsonStr = "['zero', 'one', 'two']"
JSONArray jsonArray = new JsonSlurper().parseText(jsonStr) as JSONArray
jsonArray.withIndex().each{Object str, Integer idx -> println("${idx.toString()} : ${str}")}
// OUPUT Local
// 0 : zero
// 1 : one
// 2 : two

Originally reported by solvingj, imported from: Groovy withIndex function doesn't work normally in pipeline
  • assignee: vjuranek
  • status: Open
  • priority: Minor
  • component(s): groovy-plugin
  • resolution: Unresolved
  • votes: 1
  • watchers: 2
  • imported: 20260604-161841
Raw content of original issue

Note: — While this problem can be VERY confusing to diagnose depending on the situation, it does have a very reasonable workaround: Instead of doing: jsonArray.withIndex().each{Object str, Integer index -> currentBuild.echo("${idx.toString()} : ${str}")} We can do: jsonArray.withIndex().each{Tuple2 tuple2 -> currentBuild.echo("${tuple2.first} : ${tuple2.second}")}


Groovy adds withIndex() method to iterables which turns each element into a Tuple2 of Element + index.  When using any of the groovy collection methods following withIndex(), Groovy then typically deconstructs the Tuple2 in the closure, but that doesn't seem to happen when using withIndex() on Jenkins. 

The outputs below demonstrate the issue pretty clearly.    

// Run this in a Jenkins step

String jsonStr = "['zero', 'one', 'two']"
JSONArray jsonArray = new JsonSlurper().parseText(jsonStr) as JSONArray
jsonArray.withIndex().each{Object str, Integer idx -> currentBuild.echo("${idx.toString()} : ${str}")}
// OUTPUT from jenkins
// [Pipeline] echo
// null : [zero, 0]
// [Pipeline] echo
// null : [one, 1]
// [Pipeline] echo
// null : [two, 2]

// Run this locally in a groovy file or unit test

String jsonStr = "['zero', 'one', 'two']"
JSONArray jsonArray = new JsonSlurper().parseText(jsonStr) as JSONArray
jsonArray.withIndex().each{Object str, Integer idx -> println("${idx.toString()} : ${str}")}
// OUPUT Local
// 0 : zero
// 1 : one
// 2 : two

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions