Strawberry GraphQL: Field must have a selection of subfields

This Strawberry GraphQL error occurs when you have selected a field in your GraphQL query that has subfields, but didn’t specify them. To fix this, simply add the fields you want in brackets after the field that’s causing the error. So, instead of query{ foo }, you’d put query{ foo { bar }}.

Forgetting subfields in your GraphQL queries is very common, even for developers who have been working with GraphQL for a while. I came across this error myself when working on the full-stack GraphQL example.

Before looking at the solution, let’s look at an example scenario that will cause the error.

Problem: you queried a field that has more fields within it

Let’s say you have defined your Strawberry GraphQL schema on the backend like this:

import strawberry

@strawberry.type
class Message:
    name: str
    text: str

message = Message(name="Fred", text="Hello World")

@strawberry.type
class Query:
    @strawberry.field
    async def message() -> Message:
        return message

@strawberry.type
class Mutation:
    @strawberry.field
    async def set_message(text: str) -> Message:
        message.text = text
        return message
Python

There’s a Query and a Mutation, both of which operate on a custom type called Message. There’s also message, a globally defined instance of Message which the query and mutation both work with. Normally, this would be fetched from a database, but we’re keeping it simple for the example.

Now say you have the following component in the frontend that’s querying your Strawberry GraphQL backend service:

import { useQuery } from "urql";

const GET_MESSAGE = `
    query {
        message
    }
`;

export default function Message() {
    const [{data, fetching}] = useQuery({query: GET_MESSAGE});

    if (fetching) {
        return (
            <h1>Loading...</h1>
        );
    } else {
        return (
            <h1>{data?.message.name} says: {data?.message.text}</h1>
        );
    }
}
JavaScript

Here, we’re using the GET_MESSAGE query, which is selecting just the message field defined in your GraphQL Query object above. If you’re new to GraphQL, you might think this means you’d get everything in the Message type object that’s returned.

Unfortunately, you’ll get the following error instead:

Field 'message' of type 'Message!' must have a selection of subfields. Did you mean 'message { ... }'?

GraphQL request:2:3
1 | {
2 |   message
  |   ^
3 | }

Solution: Select the fields you want

If you look back at our Strawberry schema definition, you’ll see that we have two fields defined in the Message type: name and text.

import strawberry

@strawberry.type
class Message:
    name: str
    text: str

message = Message(name="Fred", text="Hello World")
Python

Since Message has fields within it, we can’t just query it, we have to modify our query in the frontend component to pick which fields we want like this:

import { useQuery } from "urql";

const GET_MESSAGE = `
    query {
        message {
            name
            text
        }
    }
`;

export default function Message() {
JavaScript

Now, we should see the component behaving correctly:

Conclusion

GraphQL requires you to select which subfields you want when you specify a type that has them. This is a big way that GraphQL differs from standard REST APIs – they give you only the data you want, and in that way, can be much more efficient. So remember to always select subfields from your Strawberry GraphQL types.