VariableDoesNotExist: Failed lookup for key [text] in ‘None’

Tags: django

VariableDoesNotExist: Failed lookup for key [text] in 'None', that was the error that I got out of an internal django app that I wrote. The app is the most error-free one that I ever build, so I was quite surprised.

I was even more surprised when I started debugging it. The error was in the search functionality. Searching for “lizard” would give an “error 500” page. Searching for “lizar” gave 0 results (which is fine), for “lizardd”, too. “lidard” also gave 0 results. Only a search for “lizard” crashed the site.

Huh? Weird. I got the question whether I put a hidden message into this app (as “lizard” is one of our main products) :-)

Locally it all worked fine, of course. Only on the server did I see the error.

Here’s the relevant part of the traceback:

Stacktrace (most recent call last):
File "django/core/handlers/base.py", line 112, in get_response
  response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "haystack/views.py", line 50, in __call__
  return self.create_response()
File "haystack/views.py", line 144, in create_response
  return render_to_response(self.template, context, context_instance=self.context_class(self.request))
File "django/shortcuts/__init__.py", line 29, in render_to_response
  return HttpResponse(loader.render_to_string(*args, **kwargs), **httpresponse_kwargs)
File "django/template/loader.py", line 169, in render_to_string
  return t.render(context_instance)
File "django/template/base.py", line 140, in render
  return self._render(context)
...
File "django/template/base.py", line 840, in render
  bit = self.render_node(node, context)
File "django/template/debug.py", line 78, in render_node
  return node.render(context)
File "django/template/defaulttags.py", line 196, in render
  nodelist.append(node.render(context))
File "haystack/templatetags/highlight.py", line 30, in render
  text_block = self.text_block.resolve(context)
File "django/template/base.py", line 735, in resolve
  value = self._resolve_lookup(context)
File "django/template/base.py", line 781, in _resolve_lookup
  (bit, current))  # missing attribute

Eventually I found it. Via this django-haystack post. Haystack, which I use for searching, by default doesn’t deal with deleted objects. And, of course, yesterday I removed an object via the admin interface. A project with “lizard” in the title. Normally nothing is removed in this app, so the problem didn’t surface earlier.

Haystack’s results include the deleted now-non-existing object, which crashes the template. Which is a little bit weird, as normally django’s template layer is quite forgiving about None. It might be the {% highlight %} templatetag that I’m using.

Anyway, the solution is to run the update_index command with the --remove option. Or run rebuild_index. The second replaces the index, but is quicker. The first takes more resources, but leaves the index in place. Take whatever fits your usecase best.