TanStack/query · warning
Provided storage does not implement `entries` method. Remova
Error message
Provided storage does not implement `entries` method. Removal of stored entries is not possible without ability to iterate over storage items.
What it means
Dev-only error from `removeQueries` in `createPersister`. Removing persisted entries by filter requires iterating all stored keys; if `storage` lacks `entries()`, the operation cannot run and fails loudly in development (silently skipped in production).
Source
Thrown at packages/query-persist-client-core/src/createPersister.ts:357
persistedQuery = await deserialize(value)
} catch {
await storage.removeItem(key)
continue
}
if (exact) {
if (persistedQuery.queryHash !== hashKey(queryKey)) {
continue
}
} else if (!partialMatchKey(persistedQuery.queryKey, queryKey)) {
continue
}
await storage.removeItem(key)
}
}
} else if (process.env.NODE_ENV === 'development') {
throw new Error(
'Provided storage does not implement `entries` method. Removal of stored entries is not possible without ability to iterate over storage items.',
)
}
}
return {
persisterFn,
persistQuery,
persistQueryByKey,
retrieveQuery,
persisterGc,
restoreQueries,
removeQueries,
}
}
View on GitHub (pinned to 159982c80b)
Solutions
- Implement `entries()` on the storage so the filter can scan all keys.
- Use a storage with native enumeration support (`localforage`, `Map`).
- Remove entries by explicit key with `storage.removeItem(prefix + hashKey(queryKey))` instead of the bulk filter.
- Decide whether production's silent skip is acceptable for your use case.
Example fix
// before
const persister = createPersister({ storage: asyncStorage })
await persister.removeQueries({ queryKey: ['todos'] })
// after
const storage = { ...asyncStorage, entries: async () => { /* return [k,v] pairs */ } }
const persister = createPersister({ storage })
await persister.removeQueries({ queryKey: ['todos'] }) Defensive patterns
Strategy: validation
Validate before calling
function assertCanRemove(storage: any) {
if (!storage || typeof storage.entries !== 'function') {
throw new Error('removeQueries needs storage.entries()')
}
} Type guard
const canEnumerate = (s: any): s is { entries(): Promise<Iterable<[string, any]>> } =>
!!s && typeof s.entries === 'function' Try / catch
try { await persister.removeQueries({ queryKey }) } catch (e) { if (/entries method/.test((e as Error).message)) console.warn('remove skipped:', e.message) } Prevention
- Provide a storage that implements `entries()`.
- When enumeration is impossible, remove by explicit hashed key instead.
- Document the storage contract for adapter authors.
- Verify behavior in both dev and production (production skips silently).
When it happens
Trigger: Calling `removeQueries()` (or the persister's bulk-remove path) with a storage that does not implement `entries()`; custom minimal storage adapters; passing a storage stub in tests.
Common situations: AsyncStorage variants; partial polyfills; test doubles that only mock `getItem`/`setItem`/`removeItem`; adapters targeting a key-value interface without enumeration.
Related errors
- Provided storage does not implement `entries` method. Garbag
- Provided storage does not implement `entries` method. Restor
- argument is not function.
- Bad argument type. Starting with v5, only the "Object" form
- Expected enabled to be a boolean or a callback that returns
AI-assisted analysis of TanStack/query@159982c80b (2026-08-12).
Data as JSON: /api/errors/38d07e3a10039482.
Report an issue: GitHub.