             fs.unlink(@_kernel.connectionFile)
             delete @_kernel
             delete @_channels
+        if @_execute_code_queue?
+            for opts in @_execute_code_queue
+                opts.cb('closed')
+            delete @_execute_code_queue
 
     dbg: (f) =>
         if not @_dbg?

            code : required
            all  : false       # if all=true, cb(undefined, [all output messages]); used for testing mainly.
            cb   : required    # if all=false, this happens **repeatedly**:  cb(undefined, output message)
        @_ensure_running (err) =>
            if err
                opts.cb(err)
            else
                @_execute_code(opts)
        return

    _execute_code: (opts) =>
        opts = defaults opts,

        f = (mesg) =>
            if mesg.parent_header.msg_id == message.header.msg_id
                dbg("got message -- #{JSON.stringify(mesg)}")
                done = mesg.content?.execution_state == 'idle'  # check this before giving opts.cb the chance to mutate.

                # TODO: mesg isn't a normal javascript object; it's **silently** immutable, which
                # is pretty annoying for our use. For now, we just copy it, which is a waste.
                mesg = misc.copy_with(mesg,['metadata', 'content', 'buffers'])
                mesg = misc.deep_copy(mesg)
                if opts.all
                    all_mesgs.push(mesg)
                else
                    opts.cb(undefined, mesg)
                if done
                    @removeListener('iopub', f)
                    @_execute_code_queue.shift()   # finished
                    @_process_execute_code_queue()
                    if opts.all
                        opts.cb(undefined, all_mesgs)
            else
