GraphQL Error: Cannot query field "userSummary"

5 replies
Last updated: Sep 29, 2021
I'm trying to query some new fields added to my documents. These fields are an array of objects with a nested content block.
My initial approach was something like this:

// templates/project.js

export const query = graphql`
  query ProjectTemplateQuery($id: String!) {
    sampleProject: sanitySampleProject(id: { eq: $id }) {
...
      projectSummary {
        userSummary {
          _rawUserContent
        }
        problemSummary {
          _rawProblemContent
        }
        solutionSummary {
          _rawSolutionContent
        }
        tldr {
          _rawTldrContent
        }
      }
...
    }
  }
`;
But that results in this error:

Cannot query field "userSummary" on type "SanityProblemSummaryOrSolutionSummaryOrTldrOrUserSummary".
With this description
There was an error in your GraphQL query:

Cannot query field "userSummary" on type "SanityProblemSummaryOrSolutionSummaryOrTldrOrUserSummary".

...

It is recommended to explicitly type your GraphQL schema if you want to use optional fields. This way you don't have to add the mentioned "dummy content". Visit our docs to learn how you can define the schema for "SanityProblemSummaryOrSolutionSummaryOrTldrOrUserSummary":

I never defined a field with that type, but is that an autogenerated type to hold whatever objects get propagated into the array? Does anyone have any tips for how I can properly query the content? I've tried exploring it in the GraphQL playground but don't know how to query those objects with block content fields (I'm also a bit of a graphQL noob so please be nice)
AI Update

This is a common issue when working with Gatsby and Sanity's GraphQL API! The error you're seeing happens because when you have an array of different object types in Sanity, Gatsby creates a union type to represent all possible objects that could be in that array.

That long type name SanityProblemSummaryOrSolutionSummaryOrTldrOrUserSummary is indeed auto-generated by Gatsby - it's a GraphQL union type that represents "this could be a userSummary OR a problemSummary OR a solutionSummary OR a tldr object."

The solution is to use inline fragments to query each type separately:

query ProjectTemplateQuery($id: String!) {
  sampleProject: sanitySampleProject(id: { eq: $id }) {
    projectSummary {
      ... on SanityUserSummary {
        _rawUserContent
      }
      ... on SanityProblemSummary {
        _rawProblemContent
      }
      ... on SanitySolutionSummary {
        _rawSolutionContent
      }
      ... on SanityTldr {
        _rawTldrContent
      }
    }
  }
}

The ... on SanityTypeName syntax tells GraphQL "when the object is of this specific type, query these fields."

To find the exact type names, use the GraphQL playground (usually at http://localhost:8000/___graphql in development) and explore the schema. Look for types that start with Sanity and match your object type names from your Sanity schema.

Alternative approach: If you want to avoid this complexity, you could restructure your Sanity schema to use a single object type with optional fields instead of an array of different object types. However, inline fragments are the standard GraphQL pattern for querying union types, so the approach above is perfectly valid.

The gatsby-source-sanity plugin automatically generates these GraphQL types from your Sanity schema, and the _raw fields you're using are special fields unique to the Gatsby integration that provide the raw Portable Text data from Sanity.

I'm also not super knowledgeable when it comes to GQL, but I can help troubleshoot. Do you have a GQL playground link you can share?
Hey again
user M
! 👋 Yeah heres my GQL playground . FYI, my repo is based off of the
sanity-gatsby-portfolio
starter if thats helpful
So when I run this query, I don't even see
projectSummary
come up (this is the array of objects that each have a portable text field) so that I can better structure the content coming into the page. I do get a response, so the query is functioning, but I'm not sure how to access the array of objects. When I inspect them in sanity studio it doesn't seem like they have
_ids
like references, so thats why my initial approach was to nest the field name between brackets
query ProjectTemplateQuery {
    sampleProject: SampleProject(id: "791d011b-71ab-4a17-96e7-bd442663002e" ) {
      _id
      publishedAt
      categories {
        _id
        title
      }
      methods {
        _id
        name
        description
      }
      relatedProjects {
        _id
        title
        mainImage {
          asset {
            _id
          }
          alt
        }
        slug {
          current
        }
      }
      mainImage {
        crop {
          _key
          _type
          top
          bottom
          left
          right
        }
        hotspot {
          _key
          _type
          x
          y
          height
          width
        }
        asset {
          _id
        }
        alt
      }
      title
      excerptRaw
      slug {
        current
      }
      myRole
      client
      startedAt
      endedAt
      devices {
        _id
        name
        image {
          asset {
            _id
            }
          alt
          }
        }
      projectSummary {
        __typename
      }
      bodyRaw
      members {
        _key
        person {
          image {
            crop {
              _key
              _type
              top
              bottom
              left
              right
            }
            hotspot {
              _key
              _type
              x
              y
              height
              width
            }
            asset {
              _id
            }
          }
          name
        }
        roles
      }
    }
  }
Ok, I think I got it. This is a union type , so in order to access the information inside of that schema you need to use something like this:
projectSummary {
        __typename
        ... on ProblemSummary {
          _type
          _key
          problemContentRaw
        }
        ... on SolutionSummary {
          _type
          _key
          solutionContentRaw
        }
        ... on Tldr {
          _type
          _key
          tldrContentRaw
        }
        ... on UserSummary {
          _type
          _key
          userContentRaw
        }
      }
Awesome! It works in the GQL Playground!
FYI I had to make some adjustments in the
templates/project.js
file where its being applied based on the errors I was receiving and how gatsby handles those graphQL queries for some reason:
...
      projectSummary {
        ... on SanityProblemSummary {
          _type
          _key
          _rawProblemContent
        }
        ... on SanitySolutionSummary {
          _type
          _key
          _rawSolutionContent
        }
        ... on SanityTldr {
          _type
          _key
          _rawTldrContent
        }
        ... on SanityUserSummary {
          _type
          _key
          _rawUserContent
        }
      }
...
Now I'm having a bit of a harder time figuring out how to properly render these components in the gatsby front-end.
I'm trying something like this but getting errors:

function ProjectSummaryChecker(projectSummaryItem) {
  const summaryItemType = projectSummaryItem;
  let output = '';

  switch (summaryItemType) {
    case 'backgroundSummary':
      output = <BlockContent blocks={projectSummaryItem.backgroundContent || []} />
      break;
    case 'userSummary':
      output = <BlockContent blocks={projectSummaryItem.userContent || []}/>
      break;
    case 'problemSummary':
      output = <BlockContent blocks={projectSummaryItem.problemContent || []}/>
      break;
    case 'solutionSummary':
      output = <BlockContent blocks={projectSummaryItem.solutionContent || []}/>
      break;
    case 'tldr':
      output = <BlockContent blocks={projectSummaryItem.tldrContent || []}/>
      break;
    default:
      output = `Nothing in ProjectSummary found!`
      break;
  }
  return (
    `<section key=${projectSummaryItem}>${output}</section>`
  )
}


function Project(props) {
  const { _rawBody, _rawExcerpt, projectSummary, title, myRole, client, devices, startedAt, endedAt, categories, mainImage, members, publishedAt, relatedProjects } = props;
  const monthAndYearRange = projectMonthandYearRange(startedAt, endedAt);
  const projectSummaryItem = projectSummary.children;
  return (
...
        <main className={styles.mainContent}>
          <div>{projectSummary.map(ProjectSummaryChecker(projectSummaryItem))}</div>
          {_rawBody && <BlockContent blocks={_rawBody || []} />}
        </main>
...
  )
};

export default Project;
Currently this is the error I'm getting:

<section key=undefined>Nothing in ProjectSummary found!</section> is not a function

./src/components/project.js:138
Open in Editor
  136 |         </section>
  137 |         <main className={styles.mainContent}>
> 138 |           <div>{projectSummary.map(ProjectSummaryChecker(projectSummaryItem))}</div>
      |                               ^
  139 |           {_rawBody && <BlockContent blocks={_rawBody || []} />}
  140 |         </main>
  141 |         {relatedProjects && relatedProjects.length > 0 && (
And this suggests to me that the front-end isn't able to see the projectSummary info even though I've passed it through the
/template/project.js
I got some help from another friend and have been able to successfully render these fields. Thanks!

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?