-
Notifications
You must be signed in to change notification settings - Fork 4
Description
Description
When using TanStack Query with Vue 3, mutation variables are often Vue reactive() or ref() Proxy objects. The extension's mapMutationToData includes mutation.state.variables directly in the payload sent via postMessage to the content script. Since postMessage uses the structured clone algorithm, and Proxy objects are not structured-cloneable, this throws a DataCloneError on every mutation cache update.
The error is caught and logged, but it produces noisy console errors and prevents mutation data from appearing in the DevTools panel.
Console output
Error sending message to content script: DataCloneError: Failed to execute 'postMessage' on 'Window': [object Object] could not be cloned.
at U (injected.js:20:28715)
at ai.sendMutationDataUpdate (injected.js:20:31543)
at injected.js:20:31216
Root cause
In src/injected/injected.ts, mapMutationToData reads mutation.state.variables and mutation.state.data as-is:
private mapMutationToData(mutation: Mutation): MutationData {
return {
mutationId: mutation.mutationId,
state: mutation.state.status,
variables: mutation.state.variables, // may be a Vue Proxy
data: mutation.state.data, // may be a Vue Proxy
// ...
};
}When passed to sendToContentScript → window.postMessage, the structured clone algorithm fails on Proxy objects.
This is not specific to Vue — any framework that wraps objects in Proxies (Vue 3, MobX, Solid stores, etc.) will hit this issue.
Suggested fix
Deep-serialize the mutation (and query) payloads before posting, for example:
function safeClone(value: unknown): unknown {
try {
return JSON.parse(JSON.stringify(value));
} catch {
return '[Unserializable]';
}
}
private mapMutationToData(mutation: Mutation): MutationData {
return {
mutationId: mutation.mutationId,
state: mutation.state.status,
variables: safeClone(mutation.state.variables),
data: safeClone(mutation.state.data),
context: safeClone(mutation.state.context),
error: mutation.state.error,
submittedAt: mutation.state.submittedAt,
isPending: mutation.state.status === "pending",
};
}JSON.parse(JSON.stringify(...)) naturally reads through Proxy getters, producing plain objects that are safe for structured cloning. The same approach could be applied to mapQueryToData for query.state.data to prevent similar issues with query data.
Environment
- Extension version: latest from Chrome Web Store (Feb 2026)
- Framework: Vue 3 with
@tanstack/vue-query - Browser: Chrome