Skip to content

PINIA_COLADA_R0002: the cache cannot be directly set

  • Level: error (logged, dev only)

What happened

The query cache or the mutation cache was replaced by assigning to it (e.g. queryCache.caches = ...). The caches are internal reactive structures that must be modified through the cache methods, never swapped out. This will fail in production where the development check (and its error message) is removed.

How to fix it

Use the cache methods to modify entries instead of replacing the cache:

ts
const queryCache = useQueryCache()

// ✅ modify data
queryCache.setQueryData(['todos'], newTodos)

// ✅ invalidate entries
queryCache.invalidateQueries({ key: ['todos'] })

// ❌ never replace the cache itself
queryCache.caches = new Map()

Deleting entries completely

If you actually want to remove entries from the cache (not just invalidate them), use remove() on the entries instead of clearing the cache. remove() takes a single entry, so combine it with getEntries() to delete one or many:

ts
const queryCache = useQueryCache()

// remove a single entry by key (if it exists)
const entry = queryCache.get(['todos'])
if (entry) queryCache.remove(entry)

// remove every matching entry (omit the filter to clear everything)
// `active: false` skips entries still used by a mounted `useQuery()`,
// which would otherwise be recreated and refetched right away
for (const entry of queryCache.getEntries({ key: ['todos'], active: false })) {
  queryCache.remove(entry)
}

Keep these pitfalls in mind:

  • remove() clears the entry's garbage-collection timeout and deletes it from the cache, but it does not abort an in-flight request. Call queryCache.cancel(entry) (or cancelQueries(filters)) first if a fetch might still be pending.
  • Removing an entry that is still active (used by a mounted useQuery()) will cause it to be recreated and refetched on the next access, so removing rarely makes sense for active entries — prefer invalidateQueries() there.
  • getEntries() with no filter returns every entry, and getEntries({ key: ['todos'] }) matches the key and all its children. Pass exact: true to match only the exact key.

Common causes

  • Trying to "reset" the cache by assigning a new object to it
  • Spreading or cloning the cache store and writing it back
  • State management devtools or plugins replacing store state wholesale (e.g. naive store $patch/hydration logic)

Released under the MIT License.