Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-54278

Pipeline builds fail when cleanWs() in post stage

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Blocker Blocker
    • ws-cleanup-plugin
    • None
    • Plugin version 0.36

      Pipeline builds fail when cleanWs() in post stage.  Reverting to 0.35 works.

      Error reported:

      Required context class hudson.FilePath is missing
      Perhaps you forgot to surround the code with a step that provides this, such as: node
      Error when executing cleanup post condition:
      java.lang.IllegalArgumentException: Failed to prepare cleanWs step
      	at org.jenkinsci.plugins.workflow.cps.DSL.invokeDescribable(DSL.java:401)
      	at org.jenkinsci.plugins.workflow.cps.DSL.invokeMethod(DSL.java:181)
      	at org.jenkinsci.plugins.workflow.cps.CpsScript.invokeMethod(CpsScript.java:122)
      	at sun.reflect.GeneratedMethodAccessor672.invoke(Unknown Source)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      	at java.lang.reflect.Method.invoke(Method.java:498)
      	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
      	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
      	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1213)
      	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
      	at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:42)
      	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
      	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
      	at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:157)
      	at org.kohsuke.groovy.sandbox.GroovyInterceptor.onMethodCall(GroovyInterceptor.java:23)
      	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:155)
      	at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:155)
      	at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:159)
      	at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:129)
      	at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.methodCall(SandboxInvoker.java:17)
      	at WorkflowScript.run(WorkflowScript:226)
      	at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.delegateAndExecute(jar:file:/data/jenkins/plugins/pipeline-model-definition/WEB-INF/lib/pipeline-model-definition.jar!/org/jenkinsci/plugins/pipeline/modeldefinition/ModelInterpreter.groovy:133)
      	at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.runPostConditions(jar:file:/data/jenkins/plugins/pipeline-model-definition/WEB-INF/lib/pipeline-model-definition.jar!/org/jenkinsci/plugins/pipeline/modeldefinition/ModelInterpreter.groovy:757)
      	at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.catchRequiredContextForNode(jar:file:/data/jenkins/plugins/pipeline-model-definition/WEB-INF/lib/pipeline-model-definition.jar!/org/jenkinsci/plugins/pipeline/modeldefinition/ModelInterpreter.groovy:402)
      	at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.catchRequiredContextForNode(jar:file:/data/jenkins/plugins/pipeline-model-definition/WEB-INF/lib/pipeline-model-definition.jar!/org/jenkinsci/plugins/pipeline/modeldefinition/ModelInterpreter.groovy:400)
      	at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.runPostConditions(jar:file:/data/jenkins/plugins/pipeline-model-definition/WEB-INF/lib/pipeline-model-definition.jar!/org/jenkinsci/plugins/pipeline/modeldefinition/ModelInterpreter.groovy:756)
      	at com.cloudbees.groovy.cps.CpsDefaultGroovyMethods.each(CpsDefaultGroovyMethods:2030)
      	at com.cloudbees.groovy.cps.CpsDefaultGroovyMethods.each(CpsDefaultGroovyMethods:2015)
      	at com.cloudbees.groovy.cps.CpsDefaultGroovyMethods.each(CpsDefaultGroovyMethods:2056)
      	at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.runPostConditions(jar:file:/data/jenkins/plugins/pipeline-model-definition/WEB-INF/lib/pipeline-model-definition.jar!/org/jenkinsci/plugins/pipeline/modeldefinition/ModelInterpreter.groovy:751)
      	at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.executePostBuild(jar:file:/data/jenkins/plugins/pipeline-model-definition/WEB-INF/lib/pipeline-model-definition.jar!/org/jenkinsci/plugins/pipeline/modeldefinition/ModelInterpreter.groovy:728)
      	at ___cps.transform___(Native Method)
      	at com.cloudbees.groovy.cps.impl.ContinuationGroup.methodCall(ContinuationGroup.java:57)
      	at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:109)
      	at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixName(FunctionCallBlock.java:77)
      	at sun.reflect.GeneratedMethodAccessor319.invoke(Unknown Source)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      	at java.lang.reflect.Method.invoke(Method.java:498)
      	at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
      	at com.cloudbees.groovy.cps.impl.ConstantBlock.eval(ConstantBlock.java:21)
      	at com.cloudbees.groovy.cps.Next.step(Next.java:83)
      	at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:174)
      	at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:163)
      	at org.codehaus.groovy.runtime.GroovyCategorySupport$ThreadCategoryInfo.use(GroovyCategorySupport.java:129)
      	at org.codehaus.groovy.runtime.GroovyCategorySupport.use(GroovyCategorySupport.java:268)
      	at com.cloudbees.groovy.cps.Continuable.run0(Continuable.java:163)
      	at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.access$101(SandboxContinuable.java:34)
      	at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.lambda$run0$0(SandboxContinuable.java:59)
      	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox.runInSandbox(GroovySandbox.java:108)
      	at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.run0(SandboxContinuable.java:58)
      	at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:182)
      	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:332)
      	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$200(CpsThreadGroup.java:83)
      	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:244)
      	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:232)
      	at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:64)
      	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
      	at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:131)
      	at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
      	at jenkins.security.ImpersonatingExecutorService$1.run(ImpersonatingExecutorService.java:59)
      	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
      	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
      	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
      	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
      	at java.lang.Thread.run(Thread.java:748)
      Caused by: org.codehaus.groovy.runtime.InvokerInvocationException: org.jenkinsci.plugins.workflow.steps.MissingContextVariableException: Required context class hudson.FilePath is missing
      	at org.jenkinsci.plugins.workflow.cps.CpsStepContext.replay(CpsStepContext.java:499)
      	at org.jenkinsci.plugins.workflow.cps.DSL.invokeStep(DSL.java:299)
      	at org.jenkinsci.plugins.workflow.cps.DSL.invokeStep(DSL.java:209)
      	at org.jenkinsci.plugins.workflow.cps.DSL.invokeDescribable(DSL.java:399)
      	at org.jenkinsci.plugins.workflow.cps.DSL.invokeMethod(DSL.java:181)
      	at org.jenkinsci.plugins.workflow.cps.CpsScript.invokeMethod(CpsScript.java:122)
      	at sun.reflect.GeneratedMethodAccessor672.invoke(Unknown Source)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      	at java.lang.reflect.Method.invoke(Method.java:498)
      	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
      	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
      	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1213)
      	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
      	at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:42)
      	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
      	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
      	at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:157)
      	at org.kohsuke.groovy.sandbox.GroovyInterceptor.onMethodCall(GroovyInterceptor.java:23)
      	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:155)
      	at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:155)
      	at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:159)
      	at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:129)
      	at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.methodCall(SandboxInvoker.java:17)
      	... 33 more
      Caused by: org.jenkinsci.plugins.workflow.steps.MissingContextVariableException: Required context class hudson.FilePath is missing
      	at org.jenkinsci.plugins.workflow.steps.StepDescriptor.checkContextAvailability(StepDescriptor.java:260)
      	at org.jenkinsci.plugins.workflow.cps.DSL.invokeStep(DSL.java:262)
      	... 54 more 

       

      Sample pipeline:

      pipeline {
        agent any
        stages {
          stage('Test') {
            steps {
              echo 'test'
            }
          }
        }
        post {
          always {
            cleanWs()
          }
        }
      }

       

       

          [JENKINS-54278] Pipeline builds fail when cleanWs() in post stage

          I am also experiencing this problem. With the same symptoms.

          1. User starts build.
          2. Pipeline executes. 
          3. cleanWs() is the last step in a post–>always block
          4. failure with workspace cannot be delete
          5. Replay the last stage and the deletion works

          Got the failure with ws-cleanup-plugin version 0.36 installed. Downgraded to 0.35 and still got the failure.

          Info about system

          • Jenkins 2.138.2
          • ws-cleanup-plugin - 0.35 and 0.36
          • Agent is a windows machine

           

          Timothy Harris added a comment - I am also experiencing this problem. With the same symptoms. User starts build. Pipeline executes.  cleanWs() is the last step in a post–>always block failure with workspace cannot be delete Replay the last stage and the deletion works Got the failure with ws-cleanup-plugin version 0.36 installed. Downgraded to 0.35 and still got the failure. Info about system Jenkins 2.138.2 ws-cleanup-plugin - 0.35 and 0.36 Agent is a windows machine  

          Matt Dee added a comment -

          Having the exact same problem, seems completely random when it happens.
          Cannot reliably reproduce. Very annoying. 

          Jenkins ver. 2.150.3
          ws-cleanup 0.37

          Matt Dee added a comment - Having the exact same problem, seems completely random when it happens. Cannot reliably reproduce. Very annoying.  Jenkins ver. 2.150.3 ws-cleanup 0.37

          Having the same issue.

          Jenkins version - 2.164.3

          Workspace cleanup plugin - 0.37

          Elad Kollender added a comment - Having the same issue. Jenkins version - 2.164.3 Workspace cleanup plugin - 0.37

          Pat O'Shea added a comment - - edited

          Same issue here:

          Jenkins version - 2.164.3

          Workspace cleanup plugin - 0.37

          Windows agent/slave

          Pat O'Shea added a comment - - edited Same issue here: Jenkins version - 2.164.3 Workspace cleanup plugin - 0.37 Windows agent/slave

          Nick Jones added a comment -

          Same issue here, under Jenkins 2.190.3 LTS and Workspace Cleanup 0.37, on a Windows Server agent. These are the first builds of a multibranch pipeline on this particular Jenkins instance, filtered to build only a specific PR, and that same PR (thus with the same Jenkinsfile) has been building successfully on a separate Jenkins instance running all the same versions of plugins, etc. A workspace is actually being allocated on the expected node, but cleanWS() still throws this no matter how many times I restart the job.

          Nick Jones added a comment - Same issue here, under Jenkins 2.190.3 LTS and Workspace Cleanup 0.37, on a Windows Server agent. These are the first builds of a multibranch pipeline on this particular Jenkins instance, filtered to build only a specific PR, and that same PR (thus with the same Jenkinsfile) has been building successfully on a separate Jenkins instance running all the same versions of plugins, etc. A workspace is actually being allocated on the expected node, but cleanWS() still throws this no matter how many times I restart the job.

          Nick Jones added a comment -

          Aha – in my case the answer was that an error was being thrown by the build before it got into the pipeline stages, specifically by a credentials('SOME_ID') command being used in a root-level environment block, for a credential ID that didn't exist. This failed the build immediately, but because cleanWS() was in an always block, it tried to execute it, and the agent node hadn't actually been (fully?) allocated yet, hence this error. The error obscured the true root cause, and arguably cleanWs() could have been more tolerant of these conditions rather than throwing, but at least I have an explanation now.

          Nick Jones added a comment - Aha – in my case the answer was that an error was being thrown by the build before it got into the pipeline stages, specifically by a credentials('SOME_ID') command being used in a root-level environment block, for a credential ID that didn't exist. This failed the build immediately, but because cleanWS() was in an always block, it tried to execute it, and the agent node hadn't actually been (fully?) allocated yet, hence this error. The error obscured the true root cause, and arguably cleanWs() could have been more tolerant of these conditions rather than throwing, but at least I have an explanation now.

          Thanks for the report. The hypothesis of "failing in case the workspace have not been allocated yet as the build has failed before it did" sounds quite plausible. Are the any cases that cannot be explained by this?

          Oliver Gondža added a comment - Thanks for the report. The hypothesis of "failing in case the workspace have not been allocated yet as the build has failed before it did" sounds quite plausible. Are the any cases that cannot be explained by this?

          Nick Jones added a comment -

          Simple repro:

          pipeline {
            agent none
            options {
              skipDefaultCheckout(true)
            }
            stages {
              stage('Prepare') {
                steps {
                  echo 'Preparing...'
                }
              }
            }
            post {
              always {
                cleanWs deleteDirs: true
              }
            }
          }
          

          This was deliberately designed without a pipeline-level agent – it is the skeleton of an implementation I'm working on that will have stage-level agents instead – and the cleanWs failed. It seems this should be more defensively coded so that cleanWs can cleanly exit (at most with a warning) if there simply isn't a workspace to be cleaned. I'll probably end up putting cleanWs in the post blocks for stages that do use agents (which would be a better place for that command anyway), but again, I'd still expect the above to be a no-op (with possibly a warning) rather than throwing an uncaught exception.

          Nick Jones added a comment - Simple repro: pipeline { agent none options { skipDefaultCheckout( true ) } stages { stage( 'Prepare' ) { steps { echo 'Preparing...' } } } post { always { cleanWs deleteDirs: true } } } This was deliberately designed without a pipeline-level agent – it is the skeleton of an implementation I'm working on that will have stage-level agents instead – and the cleanWs failed. It seems this should be more defensively coded so that cleanWs can cleanly exit (at most with a warning) if there simply isn't a workspace to be cleaned. I'll probably end up putting cleanWs in the post blocks for stages that do use agents (which would be a better place for that command anyway), but again, I'd still expect the above to be a no-op (with possibly a warning) rather than throwing an uncaught exception.

          Aos Dabbagh added a comment - - edited

          For those of you who are stuck on this: only works if there is an agent available. If you have stage level agents, you then need to add the:

          post {
            always {
              cleanWs()
            }
          }
          

          under that specific stage. A simple example:

           

          pipeline {
            agent none
          
            options {
              timestamps()
            }
          
            stages {
              stage('Main') {
                parallel {
                  stage('Build & Test') {
                    agent {
                      label 'master'
                    }
                    stages {
                      stage('Prepare') {
                        steps {
                          echo 'Prepare...'
                        }
                      }
                    }
          
                    post {
                      always {
                        cleanWs()
                      }
                    }
                  }
          
                  stage('Debian package') {
                    agent {
                      label 'debian'
                    }
                    stages {
                      stage('Build package') {
                        steps {
                          echo 'Building package...'
                        }
                      }
                    }
          
                    post {
                      always {
                        cleanWs()
                      }
                    }
                }
              }
            }
          

          Aos Dabbagh added a comment - - edited For those of you who are stuck on this: only works if there is an agent available. If you have stage level agents, you then need to add the: post { always { cleanWs() } } under that specific stage. A simple example:   pipeline { agent none options { timestamps() } stages { stage( 'Main' ) { parallel { stage( 'Build & Test' ) { agent { label 'master' } stages { stage( 'Prepare' ) { steps { echo 'Prepare...' } } } post { always { cleanWs() } } } stage( 'Debian package ' ) { agent { label 'debian' } stages { stage( 'Build package ' ) { steps { echo 'Building package ...' } } } post { always { cleanWs() } } } } }

          Mamadou Barry added a comment -

          I'm facing the same issue. When are we going to expect a fix? Thanks

          Mamadou Barry added a comment - I'm facing the same issue. When are we going to expect a fix? Thanks

            olivergondza Oliver Gondža
            therealwaldo Will Freeman
            Votes:
            7 Vote for this issue
            Watchers:
            17 Start watching this issue

              Created:
              Updated: