# Unexpected exception when use getContext and sh together in the latest version of Jenkins

**URL:** <https://community.jenkins.io/t/unexpected-exception-when-use-getcontext-and-sh-together-in-the-latest-version-of-jenkins/828>\
**Category:** Ask a question\
**Created:** [November 17, 2021, 4:11pm UTC](https://community.jenkins.io/t/unexpected-exception-when-use-getcontext-and-sh-together-in-the-latest-version-of-jenkins/828 "2021-11-17T16:11:06Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![link89](https://dub1.discourse-cdn.com/flex013/user_avatar/community.jenkins.io/link89/32/579_2.png) [@link89](https://community.jenkins.io/u/link89)\
**Post date:** [November 17, 2021, 4:11pm UTC](https://community.jenkins.io/t/unexpected-exception-when-use-getcontext-and-sh-together-in-the-latest-version-of-jenkins/828/1 "2021-11-17T16:11:06Z")

</div>

The following code use to work properly until I upgrade the Jenkins to [Jenkins 2.303.2](https://www.jenkins.io/).

```auto
import org.jenkinsci.plugins.workflow.graph.FlowNode

node() {
    stage('hello') {
        def flow = getContext(FlowNode.class)
        echo flow.id
        sh 'echo hello' // fail in this step, very strange!
    }
}

```

Here is the error

```auto
WARNING	o.j.p.w.cps.CpsThreadGroup#saveProgramIfPossible: program state save failed
an exception which occurred:
	in field com.cloudbees.groovy.cps.impl.BlockScopeEnv.locals
	in object com.cloudbees.groovy.cps.impl.BlockScopeEnv@3aedba14
	in field com.cloudbees.groovy.cps.impl.CallEnv.caller
	in object com.cloudbees.groovy.cps.impl.FunctionCallEnv@1bd049a1
	in field com.cloudbees.groovy.cps.Continuable.e
	in object org.jenkinsci.plugins.workflow.cps.SandboxContinuable@6f0bb0e5
	in field org.jenkinsci.plugins.workflow.cps.CpsThread.program
	in object org.jenkinsci.plugins.workflow.cps.CpsThread@67734d87
	in field org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.threads
	in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@3512814b
	in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@3512814b
Caused: java.io.NotSerializableException: org.jenkinsci.plugins.workflow.cps.nodes.StepAtomNode
	at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:926)
	at org.jboss.marshalling.river.BlockMarshaller.doWriteObject(BlockMarshaller.java:65)
	at org.jboss.marshalling.river.BlockMarshaller.writeObject(BlockMarshaller.java:56)
	at org.jboss.marshalling.MarshallerObjectOutputStream.writeObjectOverride(MarshallerObjectOutputStream.java:50)
	at org.jboss.marshalling.river.RiverObjectOutputStream.writeObjectOverride(RiverObjectOutputStream.java:179)
	at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:344)
	at java.util.HashMap.internalWriteEntries(HashMap.java:1793)
	at java.util.HashMap.writeObject(HashMap.java:1363)
	at sun.reflect.GeneratedMethodAccessor43.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.jboss.marshalling.reflect.JDKSpecific$SerMethods.callWriteObject(JDKSpecific.java:156)
	at org.jboss.marshalling.reflect.SerializableClass.callWriteObject(SerializableClass.java:191)
	at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1028)
	at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:920)
	at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1082)
	at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1040)
	at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:920)
	at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1082)
	at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1040)
	at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1019)
	at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:920)
	at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1082)
	at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1040)
	at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1019)
	at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:920)
	at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1082)
	at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1040)
	at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:920)
	at org.jboss.marshalling.river.BlockMarshaller.doWriteObject(BlockMarshaller.java:65)
	at org.jboss.marshalling.river.BlockMarshaller.writeObject(BlockMarshaller.java:56)
	at org.jboss.marshalling.MarshallerObjectOutputStream.writeObjectOverride(MarshallerObjectOutputStream.java:50)
	at org.jboss.marshalling.river.RiverObjectOutputStream.writeObjectOverride(RiverObjectOutputStream.java:179)
	at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:344)
	at java.util.concurrent.ConcurrentSkipListMap.writeObject(ConcurrentSkipListMap.java:1437)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.jboss.marshalling.reflect.JDKSpecific$SerMethods.callWriteObject(JDKSpecific.java:156)
	at org.jboss.marshalling.reflect.SerializableClass.callWriteObject(SerializableClass.java:191)
	at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1028)
	at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:920)
	at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1082)
	at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1040)
	at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:920)
	at org.jboss.marshalling.AbstractObjectOutput.writeObject(AbstractObjectOutput.java:58)
	at org.jboss.marshalling.AbstractMarshaller.writeObject(AbstractMarshaller.java:111)
	at org.jenkinsci.plugins.workflow.support.pickles.serialization.RiverWriter.lambda$writeObject$0(RiverWriter.java:144)
	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox.runInSandbox(GroovySandbox.java:237)
	at org.jenkinsci.plugins.workflow.support.pickles.serialization.RiverWriter.writeObject(RiverWriter.java:143)
	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.saveProgram(CpsThreadGroup.java:557)
Caused: java.io.IOException: Failed to persist /Users/henry.xu/.jenkins/jobs/test-pipeline/builds/2/program.dat
	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.saveProgram(CpsThreadGroup.java:569)
	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.saveProgram(CpsThreadGroup.java:534)
	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.saveProgramIfPossible(CpsThreadGroup.java:517)
	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:441)
	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$400(CpsThreadGroup.java:96)
	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:312)
	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:276)
	at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:67)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:139)
	at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
	at jenkins.security.ImpersonatingExecutorService$1.run(ImpersonatingExecutorService.java:68)
	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)

```

It will work if I comment either the `getContext` or the `sh` line.  
Since it used to work properly, I guess it may be a bug of Jenkins.

---

<div class="post-metadata">

**Author:** ![timja](https://dub1.discourse-cdn.com/flex013/user_avatar/community.jenkins.io/timja/32/7_2.png) [@timja](https://community.jenkins.io/u/timja)\
**Post date:** [November 17, 2021, 8:01pm UTC](https://community.jenkins.io/t/unexpected-exception-when-use-getcontext-and-sh-together-in-the-latest-version-of-jenkins/828/2 "2021-11-17T20:01:01Z")

</div>

What are you doing this for? I doubt this is a supported feature

---

<div class="post-metadata">

**Author:** ![link89](https://dub1.discourse-cdn.com/flex013/user_avatar/community.jenkins.io/link89/32/579_2.png) [@link89](https://community.jenkins.io/u/link89)\
**Post date:** [November 18, 2021, 1:51am UTC](https://community.jenkins.io/t/unexpected-exception-when-use-getcontext-and-sh-together-in-the-latest-version-of-jenkins/828/3 "2021-11-18T01:51:35Z")

</div>

I use `getContext` to get the id of the current stage, so that I can build a link to access the log to the stage instead of the whole job. It is a formal step with document.  
[Pipeline: Basic Steps (jenkins.io)](https://www.jenkins.io/doc/pipeline/steps/workflow-basic-steps/#getcontext-get-contextual-object-from-internal-apis)  
I have used this for a long time and it works well on Jenkins 2.235.2  
But it just broken after we upgrade to Jenkins 2.303.2

---

<div class="post-metadata">

**Author:** ![bpedersen2](https://dub1.discourse-cdn.com/flex013/user_avatar/community.jenkins.io/bpedersen2/32/367_2.png) [@bpedersen2](https://community.jenkins.io/u/bpedersen2)\
**Post date:** [November 18, 2021, 9:32am UTC](https://community.jenkins.io/t/unexpected-exception-when-use-getcontext-and-sh-together-in-the-latest-version-of-jenkins/828/4 "2021-11-18T09:32:32Z")

</div>

You overlooked:  
`For use from trusted code, such as global libraries, which can manipulate internal Jenkins APIs.`  
So put in a function marked as @NonCPS could work, I guess.

```auto
import org.jenkinsci.plugins.workflow.graph.FlowNode

@NonCPS
def getFlowID() {
    def flow = getContext(FlowNode.class)
        echo flow.id
}

node() {
    stage("1") {
        getFlowID()
        sh "echo OK"
        
    }
}

```
