# Buggy code
def scanVnodes(self, gnx2body, gnx2vnode, gnx2ua, v_elements):
    c, fc = self.c, self.c.fileCommands

    # @+<< define v_element_visitor >>
    # @+node:ekr.20180605102822.1: *6* << define v_element_visitor >>
    def v_element_visitor(parent_e, parent_v):
        """Visit the given element, creating or updating the parent vnode."""
        for e in parent_e:
            assert e.tag in ("v", "vh"), e.tag
            if e.tag == "vh":
                parent_v._headString = g.toUnicode(e.text or "")
                continue
            gnx = e.attrib["t"]
            v = gnx2vnode.get(gnx)
            if v:
                # A clone
                parent_v.children.append(v)
                v.parents.append(parent_v)
                # The body overrides any previous body text.
                body = g.toUnicode(gnx2body.get(gnx) or "")
                assert g.isUnicode(body), body.__class__.__name__
                v._bodyString = body
            else:
                # @+<< Make a new vnode, linked to the parent >>
                # @+node:ekr.20180605075042.1: *7* << Make a new vnode, linked to the parent >>
                v = leoNodes.VNode(context=c, gnx=gnx)
                gnx2vnode[gnx] = v
                parent_v.children.append(v)
                v.parents.append(parent_v)
                body = g.toUnicode(gnx2body.get(gnx) or "")
                assert g.isUnicode(body), body.__class__.__name__
                v._bodyString = body
                v._headString = "PLACE HOLDER"
                # @-<< Make a new vnode, linked to the parent >>
                # @+<< handle all other v attributes >>
                # @+node:ekr.20180605075113.1: *7* << handle all other v attributes >>
                # Like fc.handleVnodeSaxAttrutes.
                #
                # The native attributes of <v> elements are a, t, vtag, tnodeList,
                # marks, expanded, and descendentTnode/VnodeUnknownAttributes.
                d = e.attrib
                s = d.get("tnodeList", "")
                tnodeList = s and s.split(",")
                if tnodeList:
                    # This tnodeList will be resolved later.
                    v.tempTnodeList = tnodeList
                s = d.get("descendentTnodeUnknownAttributes")
                if s:
                    aDict = fc.getDescendentUnknownAttributes(s, v=v)
                    if aDict:
                        fc.descendentTnodeUaDictList.append(aDict)
                s = d.get("descendentVnodeUnknownAttributes")
                if s:
                    aDict = fc.getDescendentUnknownAttributes(s, v=v)
                    if aDict:
                        fc.descendentVnodeUaDictList.append(
                            (v, aDict),
                        )
                #
                # Handle vnode uA's
                uaDict = gnx2ua.get(gnx)
                # gnx2ua is a defaultdict(dict)
                # It might already exists because of tnode uA's.
                for key, val in d.items():
                    if key not in self.nativeVnodeAttributes:
                        uaDict[key] = self.resolveUa(key, val)
                if uaDict:
                    v.unknownAttributes = uaDict
                # @-<< handle all other v attributes >>
                # Handle all inner elements.
                v_element_visitor(e, v)

    # @-<< define v_element_visitor >>
    #
    # Create the hidden root vnode.
    gnx = "hidden-root-vnode-gnx"
    hidden_v = leoNodes.VNode(context=c, gnx=gnx)
    hidden_v._headString = g.u("<hidden root vnode>")
    gnx2vnode[gnx] = hidden_v
    #
    # Traverse the tree of v elements.
    v_element_visitor(v_elements, hidden_v)
    return hidden_v


# Traceback (TypeError)
$ leogrep earthquake *.leo
Traceback (most recent call last):
File "/pri/bin/leogrep", line 151, in <module>
main()
File "/pri/bin/leogrep", line 135, in main
cmdr = bridge.openLeoFile(fpn)
File "/pri/git/leo-editor/leo/core/leoBridge.py", line 262, in openLeoFile
c = self.createFrame(fileName)
File "/pri/git/leo-editor/leo/core/leoBridge.py", line 293, in createFrame
c = g.openWithFileName(fileName)
File "/pri/git/leo-editor/leo/core/leoGlobals.py", line 3694, in openWithFileName
return g.app.loadManager.loadLocalFile(fileName, gui, old_c)
File "/pri/git/leo-editor/leo/core/leoApp.py", line 3093, in loadLocalFile
previousSettings = lm.getPreviousSettings(fn)
File "/pri/git/leo-editor/leo/core/leoApp.py", line 1999, in getPreviousSettings
c = lm.openSettingsFile(fn)
File "/pri/git/leo-editor/leo/core/leoApp.py", line 2164, in openSettingsFile
readAtFileNodesFlag=False, silent=True)
File "/pri/git/leo-editor/leo/core/leoFileCommands.py", line 652, in openLeoFile
silent=silent,
File "/pri/git/leo-editor/leo/core/leoFileCommands.py", line 515, in getLeoFile
v = FastRead(c, self.gnxDict).readFile(fileName)
File "/pri/git/leo-editor/leo/core/leoFileCommands.py", line 68, in readFile
return self.readWithElementTree(path, s)
File "/pri/git/leo-editor/leo/core/leoFileCommands.py", line 91, in readWithElementTree
hidden_v = self.scanVnodes(gnx2body, self.gnx2vnode, gnx2ua, v_elements)
File "/pri/git/leo-editor/leo/core/leoFileCommands.py", line 312, in scanVnodes
v_element_visitor(v_elements, hidden_v)
File "/pri/git/leo-editor/leo/core/leoFileCommands.py", line 297, in v_element_visitor
uaDict[key] = self.resolveUa(key, val)
TypeError: 'NoneType' object does not support item assignment

[leogrep.zip](https://github.com/leo-editor/leo-editor/files/2593365/leogrep.zip)

# Fixed code
def scanVnodes(self, gnx2body, gnx2vnode, gnx2ua, v_elements):
    c, fc = self.c, self.c.fileCommands

    # @+<< define v_element_visitor >>
    # @+node:ekr.20180605102822.1: *6* << define v_element_visitor >>
    def v_element_visitor(parent_e, parent_v):
        """Visit the given element, creating or updating the parent vnode."""
        for e in parent_e:
            assert e.tag in ("v", "vh"), e.tag
            if e.tag == "vh":
                parent_v._headString = g.toUnicode(e.text or "")
                continue
            gnx = e.attrib["t"]
            v = gnx2vnode.get(gnx)
            if v:
                # A clone
                parent_v.children.append(v)
                v.parents.append(parent_v)
                # The body overrides any previous body text.
                body = g.toUnicode(gnx2body.get(gnx) or "")
                assert g.isUnicode(body), body.__class__.__name__
                v._bodyString = body
            else:
                # @+<< Make a new vnode, linked to the parent >>
                # @+node:ekr.20180605075042.1: *7* << Make a new vnode, linked to the parent >>
                v = leoNodes.VNode(context=c, gnx=gnx)
                gnx2vnode[gnx] = v
                parent_v.children.append(v)
                v.parents.append(parent_v)
                body = g.toUnicode(gnx2body.get(gnx) or "")
                assert g.isUnicode(body), body.__class__.__name__
                v._bodyString = body
                v._headString = "PLACE HOLDER"
                # @-<< Make a new vnode, linked to the parent >>
                # @+<< handle all other v attributes >>
                # @+node:ekr.20180605075113.1: *7* << handle all other v attributes >>
                # Like fc.handleVnodeSaxAttrutes.
                #
                # The native attributes of <v> elements are a, t, vtag, tnodeList,
                # marks, expanded, and descendentTnode/VnodeUnknownAttributes.
                d = e.attrib
                s = d.get("tnodeList", "")
                tnodeList = s and s.split(",")
                if tnodeList:
                    # This tnodeList will be resolved later.
                    v.tempTnodeList = tnodeList
                s = d.get("descendentTnodeUnknownAttributes")
                if s:
                    aDict = fc.getDescendentUnknownAttributes(s, v=v)
                    if aDict:
                        fc.descendentTnodeUaDictList.append(aDict)
                s = d.get("descendentVnodeUnknownAttributes")
                if s:
                    aDict = fc.getDescendentUnknownAttributes(s, v=v)
                    if aDict:
                        fc.descendentVnodeUaDictList.append(
                            (v, aDict),
                        )
                #
                # Handle vnode uA's
                uaDict = gnx2ua[gnx]
                # gnx2ua is a defaultdict(dict)
                # It might already exists because of tnode uA's.
                for key, val in d.items():
                    if key not in self.nativeVnodeAttributes:
                        uaDict[key] = self.resolveUa(key, val)
                if uaDict:
                    v.unknownAttributes = uaDict
                # @-<< handle all other v attributes >>
                # Handle all inner elements.
                v_element_visitor(e, v)

    # @-<< define v_element_visitor >>
    #
    # Create the hidden root vnode.
    gnx = "hidden-root-vnode-gnx"
    hidden_v = leoNodes.VNode(context=c, gnx=gnx)
    hidden_v._headString = g.u("<hidden root vnode>")
    gnx2vnode[gnx] = hidden_v
    #
    # Traverse the tree of v elements.
    v_element_visitor(v_elements, hidden_v)
    return hidden_v