# Buggy code
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)


# 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 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)