gatsbyjs/gatsby · error

useStaticQuery was called with a string but expects to be ca

Error message

useStaticQuery was called with a string but expects to be called using `graphql`. Try this:

import { useStaticQuery, graphql } from 'gatsby';

useStaticQuery(graphql`${query}`);

What it means

`useStaticQuery` must receive the result of a `graphql\`...\`` tagged-template literal. That tag turns the query into a stringified numeric hash (e.g. `"3303882"`). The hook runs `Number(query)` and treats `NaN` as proof the query was never tagged, because a raw string (or any non-numeric text) is the signature of an untagged query.

Source

Thrown at packages/gatsby/cache-dir/static-query.js:72

const useStaticQuery = query => {
  if (
    typeof React.useContext !== `function` &&
    process.env.NODE_ENV === `development`
  ) {
    // TODO(v5): Remove since we require React >= 18
    throw new Error(
      `You're likely using a version of React that doesn't support Hooks\n` +
        `Please update React and ReactDOM to 16.8.0 or later to use the useStaticQuery hook.`
    )
  }

  const context = React.useContext(StaticQueryContext)

  // query is a stringified number like `3303882` when wrapped with graphql, If a user forgets
  // to wrap the query in a grqphql, then casting it to a Number results in `NaN` allowing us to
  // catch the misuse of the API and give proper direction
  if (isNaN(Number(query))) {
    throw new Error(`useStaticQuery was called with a string but expects to be called using \`graphql\`. Try this:

import { useStaticQuery, graphql } from 'gatsby';

useStaticQuery(graphql\`${query}\`);
`)
  }

  if (context[query]?.data) {
    return context[query].data
  } else {
    throw new Error(
      `The result of this StaticQuery could not be fetched.\n\n` +
        `This is likely a bug in Gatsby and if refreshing the page does not fix it, ` +
        `please open an issue in https://github.com/gatsbyjs/gatsby/issues`
    )
  }
}

View on GitHub (pinned to 8b06340921)

Solutions

  1. Add `import { useStaticQuery, graphql } from "gatsby"` and call `useStaticQuery(graphql\`...\`)`.
  2. Confirm the literal is an inline tagged template, not a variable holding a string.
  3. If using a `.graphql` file or fragment composition, still wrap the imported text with `graphql\`...\`` at the call site or use `StaticQuery` query prop instead.
  4. After fixing, restart `gatsby develop` so the query extractor re-runs.

Example fix

// before
const data = useStaticQuery(query)
// after
import { useStaticQuery, graphql } from "gatsby"
const data = useStaticQuery(graphql`
  query SiteTitleQuery { site { siteMetadata { title } } }
`)
Defensive patterns

Strategy: type-guard

Validate before calling

// useStaticQuery requires a graphql-tagged literal.
// Static lint rule: install `eslint-plugin-graphql` / Gatsby's eslint config
// and disallow plain string arguments via the `graphql/template-strings` rule.

Type guard

// A graphql-tagged literal is a string whose value is a stringified number.
function isGraphqlTagged(value: unknown): boolean {
  return typeof value === "string" && value.trim() !== "" && !Number.isNaN(Number(value))
}

Prevention

When it happens

Trigger: Calling `useStaticQuery("query { site { title } }")`, `useStaticQuery(someStringVar)`, or `useStaticQuery(query)` where `query` is a plain string and `graphql` was never imported/applied.

Common situations: Forgetting to import `graphql` from `gatsby`; copy-pasting a query from GraphiQL as a string; migrating a render-prop `StaticQuery` to `useStaticQuery` and dropping the tag; bundlers that strip or mis-order tagged-template processing.

Related errors


AI-assisted analysis of gatsbyjs/gatsby@8b06340921 (2026-08-13). Data as JSON: /api/errors/f5e2fc7dc9097028. Report an issue: GitHub.