Disabling singulizarize break graphQL

Created on 1 April 2025, 25 days ago

We are using graphql_compose 2.3 on druapl 11.1.5 on a multilingual site.

When disabling Singuliarize option in the string inflector panel of the graphQL compose settings we can't use graphQL anymore. When we go on the explorer page we have a white screen with message "this website..." with an error in Drupal watchdog (see below) and when we refresh we have the explorer but in the response panel there is a long error.

Here is the watchdog error about webonyx not able to parse a special character (that is why I mentioned we are on a multilingual setup)
GraphQL\Error\SyntaxError : Syntax Error: Cannot parse the unexpected character "\uc9". dans GraphQL\Language\Lexer->readToken() (ligne 282 de [path to]/vendor/webonyx/graphql-php/src/Language/Lexer.php).

Then after refreshing the explorer here are some of the error messages we see in response panel:

"Type Query must define one or more fields.",
"Interface field Edge.node expects type EdgeNode! but MediaDocumentEdge.node is type MediaDocument!.",
"Interface field Connection.nodes expects type [EdgeNode!]! but MediaImageConnection.nodes is type [MediaImage!]!.",
"Interface field Connection.nodes expects type [EdgeNode!]! but MediaRemoteVideoConnection.nodes is type [MediaRemoteVideo!]!."

If we just let Singuliarize option checked then everything is still working.

When looking for a solution I found this issues with similar errors but people have found that clearing the cache helped which is not the case for me.
https://www.drupal.org/project/graphql/issues/3477239 🐛 GraphQL query stops working - seems cache issue Needs work

🐛 Bug report
Status

Active

Version

2.3

Component

Code

Created by

🇧🇪Belgium davidiio

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @davidiio
  • 🇦🇺Australia almunnings Melbourne, 🇦🇺

    Yeah strange,
    How are you getting the É character into your schema...!

    The GraphQL error is a symptom.
    I saw it just now when switching between graphql 4 and 5-dev.

    Are you using 5-dev by chance? Somehow using graphql webonyx 15?
    If so, does switching to 📌 Add GraphQL 5.x support Active and clearing your cache have any positive effect?

    If not...
    HMM!

    Are you injecting your own data from somewhere else?
    The only way I was able to reproduce was to put the É character in a fieldname.

    Do you have any idea where that field is coming from?

  • 🇧🇪Belgium davidiio

    Thanks for your answer!

    We are using graphQL Version : 8.x-4.11
    Following the stacktrace the webonyx error goes back to graphql module

    /web/modules/contrib/graphql/src/Plugin/GraphQL/Schema/AlterableComposableSchema.php(173): GraphQL\Language\Parser::parse('extend type Que...', Array)

    When logging the $extensions variable it is trying to parse I have found a very long string. It looks like all the content types and terms we exposed with graphql_compose and in this string some words appear in French especialy the word "Element" is translated to "Élément" in different places like

     extend type Query {
          """List of all TermTags on the platform."""
          termTagsÉléments(
            """Returns the elements that come after the specified cursor."""
            after: Cursor
    

    or in this part that looks like a view on which we exposed the number of "element per page"

            """The page number to display."""
            page: Int = 0
            """Éléments par page. Allowed values are: 5, 10, 12, 20, 24, 25, 50."""
            pageSize: Int = 20
    

    I was able to remove the É from the "Éléments par page" by configuring the view but other strings like "termTagsÉléments" remain even when remmoving all accents from "Element" in /admin/config/regional/translate

    This is a weird string because only the "Element" word is translated and it is translated event on part of words like in "termTagsÉléments".
    We had this same issue on a prod site when activating a module and some translations were updated. Is it possible that core translation introduced some bug?

  • 🇦🇺Australia almunnings Melbourne, 🇦🇺

    Ok cool, that helps me narrow it down.
    I'll put $2 on it being this line:

    https://git.drupalcode.org/project/graphql_compose/-/blob/2.4.x/src/Lang...

    Could you try change that locally to 'items' instead of $this->t('items')
    If that works, we might either leave it as t and strip back the higher ascii.

    Thanks for your help!

  • 🇧🇪Belgium davidiio

    YES :)
    Changing $this->t('items') to 'items' does eliminate error for us.

    Thanks a lot!

  • 🇦🇺Australia almunnings Melbourne, 🇦🇺

    Aighty cool.
    So I guess, as you are the resident French speaker.

    if I changed
    Éléments
    to
    Elements

    In this scenario, would it be acceptable?

  • 🇧🇪Belgium davidiio

    Yes, I suppose.
    In french element is supposed to be "élément" (if displayed to a human reading french) but these strings are not supposed to be displayed so it is ok without accent, I would never name a variable with accents.

  • 🇦🇺Australia almunnings Melbourne, 🇦🇺
  • @almunnings opened merge request.
  • 🇧🇪Belgium davidiio

    I have used your merge request .diff file (https://git.drupalcode.org/project/graphql_compose/-/merge_requests/120....) on Drupal 11.1.5, graphql 8.x-4.11, graphql_compose 2.3.0. It applies and singuliarize option can be on or off without error.

    I might not be the best to say it is RTBC, but for me, it is working :)
    Thanks!

  • 🇦🇺Australia almunnings Melbourne, 🇦🇺

    Good enough for me!

    RE the other error you noticed, thats related to 🐛 GraphQL query stops working - seems cache issue Needs work I'm pretty sure.
    I'll merge this one in now.

    Cheers

  • 🇦🇺Australia almunnings Melbourne, 🇦🇺

    Merged to next release

  • 🇧🇪Belgium davidiio

    Sorry almunnings but I am not sure this resolves the issue.

    The approach to just add 'items' was better than adding 'elements' without accents.

    With the correction you've made in LanguageInflector.php I see termTagsElements in the explorer but have a graphql error

    {
      "errors": [
        {
          "debugMessage": "Cannot return null for non-nullable field \"Query.termTagsElements\".",
          "message": "Internal server error",
          "extensions": {
            "category": "internal"
          },
          "locations": [
            {
              "line": 2,
              "column": 3
            }
          ],
          "path": [
            "termTagsElements"
          ]
        }
      ]
    }
    

    If I override code with $plural .= '_items'; instead of $plural .= '_' . u($suffix)->ascii()->lower()->toString(); I end up with termTagsItems which is working without errors

  • 🇦🇺Australia almunnings Melbourne, 🇦🇺

    Oh, bummer.
    I'm fine with items.

    It's a pretty universal word throughout programming.

    Just set the fallback to "items" you think?

  • 🇧🇪Belgium davidiio

    To be honest I don't know what is this part of graphql_compose code supposed to do, I don't have use for pluralizing or singularizing my content type name or field name because If I name it Tags in Drupal it is because I want it to be plural why would I use a feature to singularize it?
    Plus It is possible to rename fields in graphql compose schemas.

    For me, if "items" works and "elements" does not, go for "items" bu I have no idea what I am doing here, please do what is best for your module.

  • 🇦🇺Australia almunnings Melbourne, 🇦🇺

    Yeah it might not be immediately clear, but tags is already plural, so if we want to load multiple tags… we end up with some kind of naming convention hell

    Tags tagss tagsies?
    News newss newsies?
    Media medion medias

    It gets weird fast
    Items seemed to work universally in English.

    To sum it up quickly, we singularise (optionally) something and then pluralise it for the edge loaders, so you can have a nodePage and nodePages query.

    The singular form of news is news. The plural of news is news. If your item is named tags and we pluralise it, it’s already plural.

    So we end up with a conflict. That’s where items comes in.

    It works in some instances with things like tags. The singular item becomes tag and the plural tags. The system works.

    There’s a hook to alter the naming also. I forget off the top of my head.

    Basically tricky as help to make everything work for every and make sense. lol.

    Its mostly just a design pattern that was core at the start and now we roll with it.

  • 🇧🇪Belgium davidiio

    Thanks almunnings I understand now why it is necessary, but still I don't get why "items" is working and "elements" does not if it is just a way to differenciate singular and plural forms any kind of suffix could do, right?

    Anyway, I agree that "items" is a pretty universal word to understand that it is somehow about multiple units and if it is working it is best to use that instead of trying to make it in multiple languages.

  • 🇦🇺Australia almunnings Melbourne, 🇦🇺

    Yeah elements really should work. I’ll look into reproducing your error today at lunch.

    If I can replicate, I can eliminate 🔫😎

  • @almunnings opened merge request.
  • 🇦🇺Australia almunnings Melbourne, 🇦🇺

    I'm just going to push this into dev, have a play around. if cool, we can let this one be done.

  • Just had a similar issue on a multilingual site. We've always had Singuliarize disabled, but after updating a piece of content the whole graphql server seemed to go down. In explorer this is the error we got. I did find that just saving configuration in compose resolved it, or truncation the cache tables, drush cr didn't seem to work for some reason.

    {
      "errors": [
        {
          "message": "Type Query must define one or more fields.",
          "stack": "GraphQLError: Type Query must define one or more fields.\n    at t.reportError (/modules/contrib/graphql/assets/explorer/dist/bundle.min.js?v=10.4.5:2:695470)\n    at b (/modules/contrib/graphql/assets/explorer/dist/bundle.min.js?v=10.4.5:2:695849)\n    at /modules/contrib/graphql/assets/explorer/dist/bundle.min.js?v=10.4.5:2:694963\n    at h (/modules/contrib/graphql/assets/explorer/dist/bundle.min.js?v=10.4.5:2:695133)\n    at /modules/contrib/graphql/assets/explorer/dist/bundle.min.js?v=10.4.5:2:1145894\n    at Object.Xa [as useMemo] (/modules/contrib/graphql/assets/explorer/dist/bundle.min.js?v=10.4.5:2:462600)\n    at t.useMemo (/modules/contrib/graphql/assets/explorer/dist/bundle.min.js?v=10.4.5:2:531004)\n    at SchemaContextProvider (/modules/contrib/graphql/assets/explorer/dist/bundle.min.js?v=10.4.5:2:1145872)\n    at ka (/modules/contrib/graphql/assets/explorer/dist/bundle.min.js?v=10.4.5:2:458224)\n    at As (/modules/contrib/graphql/assets/explorer/dist/bundle.min.js?v=10.4.5:2:469805)"
        }
      ]
    }
  • 🇦🇺Australia almunnings Melbourne, 🇦🇺

    So is dev working for you? I’ll push a release if so.

  • The problem is I need find a way to replicate the issue as it only seems to manifest itself on a rare occasion, and I'm not 100% sure the exact cause as yet. I've got a database with a broken cache/schema but just updating to the dev version doesn't fix it, I still needed to clear the cache. I'll see i can replicate and get back to you.

Production build 0.71.5 2024