Using cache tag on array outputs nothing
The {% cache %} tag is only designed to do one thing – to capture output (e.g. HTML) and store that output to the database, so that the next time Craft encounters that particular cache tag, it can serve up the cached output from the database, instead of having to run whatever code is contained inside the {% cache %} tag pair, on every pageload.

In your code, you're attempting to cache a variable (data). That won't work. Essentially, you're just feeding the {% cache %} tag empty output, and the code that actually sets the data variable will only run on the first pageload (or whenever the cache has been cleared out). On subsequent pageloads, Craft won't bother to actually run the code inside the {% cache %} tag, it'll simply print whatever output was stored for that particular cache (which, in this case, is empty). Hence your code breaking.

What you need to do, is to revise your caching strategy so that your business logic (i.e. the part of your code that pulls and operates on data – which is usually the expensive part, resource-wise) and the part that actually prints your data is contained within the same {% cache %} tag pair.

Here's a small example to illustrate good vs. bad use of the {% cache %} tag:

Bad

{% cache %}
    {% set entries = craft.entries.section('news') %}
{% endcache %}

{% for entry in entries %}
    &lt;a href="{{ entry.url }}"&gt;{{ entry.title }}&lt;/a&gt;&lt;br /&gt;
{% endfor %}


^ Ouch. The variable entries will only be set whenever the cache is empty; on subsequent pageloads, Craft will serve up an empty, cached string instead of actually running the craft.entries query and the for loop will fail because it'll operate on a variable that isn't set.

Good

{% cache %}

    {% set entries = craft.entries.section('news') %}

    {% for entry in entries %}
        &lt;a href="{{ entry.url }}"&gt;{{ entry.title }}&lt;/a&gt;&lt;br /&gt;
    {% endfor %}

{% endcache %}


^ Awesome. The page will probably be served a bit faster because Craft doesn't have to pull the entries and compile the HTML for every pageload – it'll just spit out the output resulting from the code within the {% cache %} tag.