@@ -708,9 +708,9 @@ def create(self, user_id: str, conversation_id: str) -> str:
708708 container , stream = self ._spawn (meta )
709709 except Exception :
710710 # tolerate a failed spawn like ServerRunner: retried at exec
711- container , stream = None , None # type: ignore[assignment]
711+ container , stream = None , None
712712 with self ._lock :
713- if container is not None :
713+ if container is not None and stream is not None :
714714 self ._containers [sandbox_id ] = container
715715 self ._streams [sandbox_id ] = stream
716716 self ._locks [sandbox_id ] = threading .Lock ()
@@ -887,11 +887,15 @@ def _exec_run_locked(
887887 # single ready line is consumed) and block until the watchdog
888888 meta ["ready_ok" ] = True
889889 elif not meta .get ("ready_ok" ):
890- if not self ._read_ready (stream ):
890+ if stream is None or not self ._read_ready (stream ):
891891 return ExecResult (
892892 exit_code = None , stdout = "" , stderr = "harness container died before ready"
893893 )
894894 meta ["ready_ok" ] = True
895+ if stream is None :
896+ # alive container with no stream handle is a corrupt state;
897+ # fail the run clearly rather than proceed with None
898+ return ExecResult (exit_code = None , stdout = "" , stderr = "sandbox stream unavailable" )
895899 self .touch (sandbox_id )
896900 err_from = len (meta ["stderr_log" ])
897901 with self ._lock :
0 commit comments