Cms: GraphQL error after updating to 3.5 - Expected a value of type \"String\" but received: []

Created on 26 Aug 2020  路  6Comments  路  Source: craftcms/cms

Description

This occurs on a single field author when it's selected from a specific position. It's seems not related to the asset itself as the error persist when choosing another asset. The author-field is populated with text in the control panel.

This query:

query GetPage($slug: [String]) {
  entry(site: "*", uri: $slug) {
    ...startpageFields
  }
}

fragment startpageFields on startpage_startpage_Entry {  
  blocks: startpageBlocks {
    ... on startpageBlocks_news_BlockType {      
      children {        
        ... on startpageBlocks_blogBlock_BlockType {          
          image {
            ... on local_Asset {
              metaDescription
              author
            }
          }
        }        
      }
      newsEntries {
        ... on newspage_newspage_Entry {
          cardImg: heroimage {
            ... on local_Asset {
              metaDescription
              author
            }
          }
        }
      }
    }
  }
}

Results in this

{
  "errors": [
    {
      "debugMessage": "Expected a value of type \"String\" but received: []",
      "message": "Internal server error",
      "category": "internal",
      "locations": [
        {
          "line": 15,
          "column": 15
        }
      ],
      "path": [
        "entry",
        "blocks",
        4,
        "children",
        1,
        "image",
        0,
        "author"
      ]
    }
  ],
  "data": {
    "entry": {
      "blocks": [
        {},
        {},
        {},
        {},
        {
          "children": [
            {},
            {
              "image": [
                {
                  "metaDescription": "Text",
                  "author": null
                }
              ]
            }
          ],
          "newsEntries": [
            {
              "cardImg": [
                {
                  "metaDescription": "Text",
                  "author": "Text"
                }
              ]
            },
            {
              "cardImg": [
                {
                  "metaDescription": "Text",
                  "author": "Text"
                }
              ]
            },
            {
              "cardImg": [
                {
                  "metaDescription": "Text",
                  "author": "Text"
                }
              ]
            }
          ]
        },
        {},
        {}
      ]
    }
  }
}

Running exactly the same query on Craft 3.4.26 produces this response:

{
  "data": {
    "entry": {
      "blocks": [
        {},
        {},
        {},
        {},
        {
          "children": [
            {},
            {
              "image": [
                {
                  "metaDescription": "Text",
                  "author": "Text"
                }
              ]
            }
          ],
          "newsEntries": [
            {
              "cardImg": [
                {
                  "metaDescription": "Text",
                  "author": "Text"
                }
              ]
            },
            {
              "cardImg": [
                {
                  "metaDescription": "Text",
                  "author": "Text"
                }
              ]
            },
            {
              "cardImg": [
                {
                  "metaDescription": "Text",
                  "author": "Text"
                }
              ]
            }
          ]
        },
        {},
        {}
      ]
    }
  }
}

Steps to reproduce

Startpage is a single, having a Neo-block structure where local_Asset is an Asset that has the author Plain text field.

Additional info

  • Craft version: Craft Pro 3.5.6
  • PHP version: 7.4.9
  • Database driver & version: MySQL 5.5.5
  • Plugins & versions:

AD Login 0.1.0
Azure Blob Remote Volume 1.0.2
Healthz v1.0.3
Navigation 1.3.27
Neo 2.8.6
Redactor 2.7.2
Relation delete check 0.1.0
Socializer 1.1.0
Webhooks 2.3.2

bug graphql normal

All 6 comments

Hmm. On a gut level, this sounds like an issue with the eager-load condition builder in Craft 3.5. I'll look into this!

I'm unable to reproduce this locally. Can you send over a DB dump, composer.lock and composer.json files? If so, can you send them over to [email protected] and reference this issue?

Absolutely, email has been sent. Thanks for looking at this!

Got them, looking into that. It definitely is a bug in the eager-loading logic.

Okay, so this issue had multiple layers to this.

1) Eager-loading condition builder changes.

GraphQL queries will always have a tendency to lean heavily on relations and are prone to be performance-heavy. For that reason, each query is analyzed and all the eager-loading parameters are built to the best of Craft's abilities. This was refactored in 3.5 and, along with this refactor, support for missing "special" fields was added - such as "author".

2) Neo field does not support eager-loading for children (https://github.com/spicywebau/craft-neo/blob/master/src/gql/types/elements/Block.php#L45).

This caused Craft to to try to figure out eager-loading for everything nested under the children, at least to salvavge some performance. This was also introduced in Craft 3.5.

3) Plugins needed a way to tell Craft about their eager-loadable fields.

This also happened in Craft 3.5 and, since not everything can be eagerloaded everywhere, there was a mechanism introduced where you could specify under what kind of a parent could certain fields be eager-loaded. For example, "author" field can only be eager-loaded on entries.

4) Eager-loadable fields are always allowed on top level of a query.

This is because then the conditions for allowing or disallowing an eager-loadable field need to look at both what Craft field/element are we currently traversing as well as GraphQL return types and that is not very feasible in the long term. For example, if you eager-load "author", if I know that I'm currently traversing an Entry field, I'll allow it. However, if I know that I'm at the top of the query currently, I would have to create a map of query return types and element types and it just becomes a huge mess.


So that's the background for the bug. The actual bug was that when Craft encountered (2) in your query, it started a new eager-loading chain. However, this also triggered (4) to assume it was a top-level query and try to eager-load "author" when it was, in reality, inside an Asset field, not at the top of the query, as Craft believed. So I just fixed that part.

Anyway, this will be a part of the next 3.5 release!

Craft 3.5.8 is out now with these changes.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

leigeber picture leigeber  路  3Comments

angrybrad picture angrybrad  路  3Comments

timkelty picture timkelty  路  3Comments

angrybrad picture angrybrad  路  3Comments

RitterKnightCreative picture RitterKnightCreative  路  3Comments