How to fix Bad argument type. Expected array for queryKey but got object in React

ReactBEGINNERMEDIUMUpdated Dec 10, 2025ยท 119 views

This error occurs when React Query receives an object directly as the queryKey instead of the required array format. While query keys can contain objects as elements within the array, the queryKey itself must always be an array. Understanding the correct queryKey structure prevents cache mismatches and query function errors.

Quick fix

Fixes Bad argument type. Expected array for queryKey but got object

// WRONG - passing object directly
const { data } = useQuery({
  queryKey: { userId: 1, filter: "active" },
  queryFn: fetchUser
});

// CORRECT - object wrapped in array
const { data } = useQuery({
  queryKey: [{ userId: 1, filter: "active" }],
  queryFn: fetchUser
});

// BEST PRACTICE - use a descriptive string first
const { data } = useQuery({
  queryKey: ["user", { userId: 1, filter: "active" }],
  queryFn: fetchUser
});
  1. Check your queryKey format and wrap it in an array
  2. Use the correct queryKey structure with strings and objects
  3. Check for typos in the queryKey property name
  4. Convert string keys to array format if upgrading from React Query v2
react โ€” error
// WRONG - passing object directly
const { data } = useQuery({
queryKey: { userId: 1, filter: "active" },
queryFn: fetchUser
});
// CORRECT - object wrapped in array
const { data } = useQuery({
queryKey: [{ userId: 1, filter: "active" }],
queryFn: fetchUser
});
// BEST PRACTICE - use a descriptive string first
const { data } = useQuery({
queryKey: ["user", { userId: 1, filter: "active" }],
queryFn: fetchUser
});
Bad argument type. Expected array for queryKey but got object

What this error means

React Query (TanStack Query) uses query keys to uniquely identify and cache queries. The queryKey parameter must be an array at the top level - this is a strict requirement of the library. When you pass an object directly instead of wrapping it in an array, React Query cannot properly process the key for caching, invalidation, or refetching. The library expects the format `queryKey: [...]` where the array can contain strings, numbers, and objects as elements. This error specifically occurs when you accidentally pass `queryKey: {...}` (a plain object) instead of `queryKey: [{...}]` (an array containing an object). The array structure allows React Query to perform hierarchical matching when invalidating queries and ensures consistent key serialization across your application.

Typical symptoms

  • Error message: "Bad argument type. Expected array for queryKey but got object"
  • useQuery or useMutation hooks fail to execute and return errors
  • TypeScript shows type errors on queryKey property if using strict typing
  • Query data not caching properly or appearing as undefined
  • queryClient.invalidateQueries or getQueryData methods fail when called
  • Query functions never execute despite being defined correctly
  • React Query DevTools show malformed or missing query keys

Common causes

  1. Passing an object directly as queryKey instead of wrapping it in an array: queryKey: { userId: 1 } instead of queryKey: [{ userId: 1 }]
  2. Accidentally passing the entire query options object as queryKey instead of just the key property
  3. Typo in the property name: writing "gueryKey" or "querykey" instead of "queryKey"
  4. Destructuring error where you extract the wrong variable and pass it as queryKey
  5. Using old React Query v2 syntax where string keys were allowed, but now upgrading to v3+ which requires arrays
  6. Copy-pasting code from outdated tutorials or documentation that used non-array keys
  7. Passing a query parameter object meant for the query function directly to queryKey
  8. Using a function that returns an object instead of an array for dynamic query keys

How to fix "Bad argument type. Expected array for queryKey but got object"

1Check your queryKey format and wrap it in an array

Locate the useQuery or useMutation call that is causing the error. Ensure the queryKey is an array. If you have an object with query parameters, wrap it in an array.

typescript
// WRONG - passing object directly
const { data } = useQuery({
  queryKey: { userId: 1, filter: "active" },
  queryFn: fetchUser
});

// CORRECT - object wrapped in array
const { data } = useQuery({
  queryKey: [{ userId: 1, filter: "active" }],
  queryFn: fetchUser
});

// BEST PRACTICE - use a descriptive string first
const { data } = useQuery({
  queryKey: ["user", { userId: 1, filter: "active" }],
  queryFn: fetchUser
});
2Use the correct queryKey structure with strings and objects

Follow React Query best practices by starting with a descriptive string identifier, then adding variables. The array format allows React Query to match query keys hierarchically for invalidation.

typescript
// Simple query with no parameters
const { data: todos } = useQuery({
  queryKey: ["todos"],
  queryFn: fetchTodos
});

// Query with a single parameter
const { data: todo } = useQuery({
  queryKey: ["todo", todoId],
  queryFn: () => fetchTodo(todoId)
});

// Query with multiple parameters
const { data: filteredTodos } = useQuery({
  queryKey: ["todos", { status: "done", page: 1 }],
  queryFn: () => fetchTodos({ status: "done", page: 1 })
});
3Check for typos in the queryKey property name

A common mistake is misspelling "queryKey". React Query will not recognize the property and may default to undefined or throw a type error.

typescript
// WRONG - typo in property name
const { data } = useQuery({
  gueryKey: ["todos"], // typo: "gueryKey" instead of "queryKey"
  queryFn: fetchTodos
});

// WRONG - incorrect casing
const { data } = useQuery({
  querykey: ["todos"], // should be "queryKey" with capital K
  queryFn: fetchTodos
});

// CORRECT
const { data } = useQuery({
  queryKey: ["todos"],
  queryFn: fetchTodos
});
4Convert string keys to array format if upgrading from React Query v2

If you are migrating from an older version of React Query, you may have string query keys that need to be converted to arrays. React Query v3 and later require array format.

typescript
// OLD (React Query v2)
const { data } = useQuery("todos", fetchTodos);

// NEW (React Query v3+)
const { data } = useQuery({
  queryKey: ["todos"],
  queryFn: fetchTodos
});
5Verify dynamic query key functions return arrays

If you use a function or factory to generate query keys dynamically, ensure it returns an array, not an object.

typescript
// WRONG - function returns object
const getUserKey = (userId: number) => ({ userId });

const { data } = useQuery({
  queryKey: getUserKey(1), // returns object, not array
  queryFn: () => fetchUser(1)
});

// CORRECT - function returns array
const getUserKey = (userId: number) => ["user", userId];

const { data } = useQuery({
  queryKey: getUserKey(1), // returns ["user", 1]
  queryFn: () => fetchUser(1)
});

// BETTER - function returns array with object
const getUserKey = (userId: number, options?: object) => 
  ["user", { userId, ...options }];

const { data } = useQuery({
  queryKey: getUserKey(1, { includeProfile: true }),
  queryFn: () => fetchUser(1)
});
6Inspect query invalidation and client method calls

If the error occurs during query invalidation or when calling queryClient methods, ensure you pass array keys there as well.

typescript
// WRONG - passing object to invalidateQueries
queryClient.invalidateQueries({ userId: 1 });

// CORRECT - passing array with object
queryClient.invalidateQueries({ queryKey: ["user", { userId: 1 }] });

// CORRECT - invalidating all queries matching prefix
queryClient.invalidateQueries({ queryKey: ["user"] });
7Enable TypeScript strict mode to catch these errors at compile time

If you are using TypeScript, ensure you have strict type checking enabled. React Query types will prevent you from passing incorrect queryKey formats.

typescript
// In tsconfig.json
{
  "compilerOptions": {
    "strict": true
  }
}

With strict mode enabled, TypeScript will show an error if you try to pass a non-array queryKey:

typescript
// TypeScript will error before runtime
const { data } = useQuery({
  queryKey: { userId: 1 }, // Type error: object is not assignable to QueryKey
  queryFn: fetchUser
});

Advanced notes

React Query uses query keys for more than just identification - they are the foundation of its caching and invalidation system. The array structure allows hierarchical matching, meaning queryClient.invalidateQueries({ queryKey: ["todos"] }) will match all keys starting with "todos", such as ["todos"], ["todos", 1], and ["todos", { status: "done" }]. Object property order within array elements does not matter for equality - ["todos", { status, page }] and ["todos", { page, status }] are considered identical. However, array element order does matter - ["todos", status, page] and ["todos", page, status] are different keys. For complex applications, consider creating query key factories that encapsulate key generation logic and ensure consistency. For example, const todoKeys = { all: ["todos"] as const, lists: () => [...todoKeys.all, "list"] as const, list: (filters: string) => [...todoKeys.lists(), { filters }] as const }. This pattern prevents typos and makes refactoring easier. Always include any variables your query function depends on in the queryKey array - this ensures queries refetch automatically when dependencies change.

Frequently asked questions

What does "Bad argument type. Expected array for queryKey but got object" mean?
React Query (TanStack Query) uses query keys to uniquely identify and cache queries. The queryKey parameter must be an array at the top level - this is a strict requirement of the library. When you pass an object directly instead of wrapping it in an array, React Query cannot properly process the key for caching, invalidation, or refetching.
How do I fix "Bad argument type. Expected array for queryKey but got object"?
This error occurs when React Query receives an object directly as the queryKey instead of the required array format. While query keys can contain objects as elements within the array, the queryKey itself must always be an array. Understanding the correct queryKey structure prevents cache mismatches and query function errors.
What causes "Bad argument type. Expected array for queryKey but got object"?
Passing an object directly as queryKey instead of wrapping it in an array: queryKey: { userId: 1 } instead of queryKey: [{ userId: 1 }] Accidentally passing the entire query options object as queryKey instead of just the key property Typo in the property name: writing "gueryKey" or "querykey" instead of "queryKey"
Is the "Bad argument type. Expected array for queryKey but got object" error serious?
It is a medium-severity error โ€” more of a blocker than a risk. The steps above resolve it.

Official resources & further reading