'Invalid use of comma' error on simple GraphQL get queries

Moved from GitHub dgraph/5175

Posted by CosmicPangolin:

What version of Dgraph are you using?

v20.0.3

Have you tried reproducing the issue with the latest release?

Docker image is ‘latest,’ updated 3/30

What is the hardware spec (RAM, OS)?

Google Cloud VM (8gb)

Steps to reproduce the issue (command/config used to run Dgraph).

Run Dgraph in docker, upload simple schema, save data with mutation, try to query with getType. From Insomnia:

{
  getUser(id: "abcd") {
    id
  }
}

{
  "errors": [
    {
      "message": "Dgraph query failed because Dgraph query failed because line 2 column 19: Invalid use of comma."
    }
  ]
}

Expected behaviour and actual result.

queryType works fine; only getType fails with this error. Mutations also seem to work.

CosmicPangolin commented :

This seems related to defining the primary ‘id’ field to take a String with the @id directive

MichelDiz commented :

Can you share the JSON export from Insomnia?

CosmicPangolin commented :

@MichelDiz Sorry, what did you need exactly? This?

> POST /graphql HTTP/1.1
> Host: blablabla/graphql
> User-Agent: insomnia/7.1.1
> Content-Type: application/json
> Accept: */*
> Content-Length: 58

| {"query":"{\n  getUser(id: \"abcd\") {\n    id\n  }\n}\n"}

What I found was that this schema works fine:

interface Entity {
    id: ID!
    type: String!
    createdTime: Int
    updatedTime: Int
}

but this does not:

interface Entity {
    id: String! @id
    type: String!
    createdTime: Int
    updatedTime: Int
}

Still not entirely sure what the @id directive does besides guarantee uniqueness, but it looked like the query logic still assumed that the ‘id’ field matches a hex value…I’d have to seed a new db to check again, but I’m pretty sure that error didn’t throw if I passed in a ‘0x1’ value given the schema with that second interface.

MichelDiz commented :

This export

This gives us exact what happened in your side.

CosmicPangolin commented :

@MichelDiz Github doesn’t support JSON attachments - pasting contents here:

queryUser (works as expected):
{"_type":"export","__export_format":4,"__export_date":"2020-04-14T22:29:18.186Z","__export_source":"insomnia.desktop.app:v7.1.1","resources":[{"_id":"req_a126d4c903944c2ab97dadf5dd270ff9","authentication":{},"body":{"mimeType":"application/graphql","text":"{\"query\":\"{\\n queryUser {\\n id\\n }\\n}\\n\"}"},"created":1586808902439,"description":"","headers":[{"id":"pair_d804e6aeab47421db40282a9c25eeb00","name":"Content-Type","value":"application/json"}],"isPrivate":false,"metaSortKey":-1586808902439,"method":"POST","modified":1586903303086,"name":"GraphQL","parameters":[],"parentId":"wrk_6a8d40e11c754cf991d13e6ea635222e","settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingFollowRedirects":"global","settingRebuildPath":true,"settingSendCookies":true,"settingStoreCookies":true,"url":"http://***redacted***:8080/graphql","_type":"request"},{"_id":"wrk_6a8d40e11c754cf991d13e6ea635222e","created":1586808683023,"description":"","modified":1586808683023,"name":"Insomnia","parentId":null,"_type":"workspace"},{"_id":"env_5bfff293cf4a2c1bf926ba75399611440bfad391","color":null,"created":1586808683077,"data":{},"dataPropertyOrder":null,"isPrivate":false,"metaSortKey":1586808683077,"modified":1586808683077,"name":"Base Environment","parentId":"wrk_6a8d40e11c754cf991d13e6ea635222e","_type":"environment"},{"_id":"jar_5bfff293cf4a2c1bf926ba75399611440bfad391","cookies":[],"created":1586808683081,"modified":1586808683081,"name":"Default Jar","parentId":"wrk_6a8d40e11c754cf991d13e6ea635222e","_type":"cookie_jar"}]}

getUser (comma error):
{"_type":"export","__export_format":4,"__export_date":"2020-04-14T22:31:19.886Z","__export_source":"insomnia.desktop.app:v7.1.1","resources":[{"_id":"req_a126d4c903944c2ab97dadf5dd270ff9","authentication":{},"body":{"mimeType":"application/graphql","text":"{\"query\":\"{\\n getUser(id: \\\"rn77BX1bUvRYvkOTH2ucPwrFbyn2\\\") {\\n id\\n }\\n}\\n\"}"},"created":1586808902439,"description":"","headers":[{"id":"pair_d804e6aeab47421db40282a9c25eeb00","name":"Content-Type","value":"application/json"}],"isPrivate":false,"metaSortKey":-1586808902439,"method":"POST","modified":1586903455018,"name":"GraphQL","parameters":[],"parentId":"wrk_6a8d40e11c754cf991d13e6ea635222e","settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingFollowRedirects":"global","settingRebuildPath":true,"settingSendCookies":true,"settingStoreCookies":true,"url":"http://***redacted***:8080/graphql","_type":"request"},{"_id":"wrk_6a8d40e11c754cf991d13e6ea635222e","created":1586808683023,"description":"","modified":1586808683023,"name":"Insomnia","parentId":null,"_type":"workspace"},{"_id":"env_5bfff293cf4a2c1bf926ba75399611440bfad391","color":null,"created":1586808683077,"data":{},"dataPropertyOrder":null,"isPrivate":false,"metaSortKey":1586808683077,"modified":1586808683077,"name":"Base Environment","parentId":"wrk_6a8d40e11c754cf991d13e6ea635222e","_type":"environment"},{"_id":"jar_5bfff293cf4a2c1bf926ba75399611440bfad391","cookies":[],"created":1586808683081,"modified":1586808683081,"name":"Default Jar","parentId":"wrk_6a8d40e11c754cf991d13e6ea635222e","_type":"cookie_jar"}]}

MichelDiz commented :

np, but you can always use Pastebin, gist or similar tho. Thanks. I gonna check it.

MichaelJCompton commented :

Hi @CosmicPangolin can you please post a full schema showing the issue and the queries/mutations that you are trying, so that I can reproduce.

CosmicPangolin commented :

Works:

interface Entity {
    id: ID!
    type: String!
    createdTime: Int
    updatedTime: Int
}

interface File {
    fileName: String!
    downloadUrl: String!
}

type Image implements Entity & File {
    resolution: String
}

type User implements Entity {
    firebaseUserId: String! @id
    handle: String! @search(by: [regexp])
    displayName: String! @search(by: [regexp])
    email: String!
    birthday: String
    profilePhoto: Image
}

No works:

interface Entity {
    id: String! @id
    type: String!
    createdTime: Int
    updatedTime: Int
}

interface File {
    fileName: String!
    downloadUrl: String!
}

type Image implements Entity & File {
    resolution: String
}

type User implements Entity {
    handle: String! @search(by: [regexp])
    displayName: String! @search(by: [regexp])
    email: String!
    birthday: String
    profilePhoto: Image
}

I’m just saving a simple user successfully with addUser ($user is serialized from class and sent as a variable through the generic GraphQL Dart client) -

mutation AddUser($user: AddUserInput!) {
          addUser(input: [$user]) {
            user {
              id   
            }
          }
        }

and querying using the queries posted above - queryUser, getUser. User is saved fine, nothing special - queryUser returns all fields as expected, including String ‘id’. Only getUser fails. :slight_smile:

1 Like

CosmicPangolin commented :

@MichelDiz @MichaelJCompton

Hey guys, any thoughts here? Beyond this issue, there are a few other ID-related features of the GraphQL API that have felt a bit unnatural in my quest to build a generic repo for handling my data models:

  • The TypePatch object for TypeUpdate mutations doesn’t seem to map ID! or @id fields since they are passed in ‘filter’, which means users must null these fields before locally serializing data models…in my case, I have that firebaseUserId field that I don’t even want to be nullable

  • For TypeUpdate mutations, “filter” on String @id fields requires StringHashObject, when we only need [String] for ID! fields. In general I feel like it would be useful to have some Update mutation examples on the site since that has the most irregular input shape but is only mentioned in passing.

  • Most things I’ve bumped up against have just thrown ‘unknown location’ errors. It’s taken a few rough days of deep schema introspection and trial/error to identify these issues around constructing mutations and serializing data, given nesting and custom IDs.

MichaelJCompton commented :

@CosmicPangolin

Hi, looks like there is a bug in @id when it’s on an interface. I’ll get someone to look and we’ll patch into 20.03.2.

As for your other points:

  1. Yeah, that sounds sensible. The goal is for users to just be able to serialize their client side data and send it in. I can see that not having ids (both @id and ID) in those types makes that more difficult. I think what we’ll do is accept them as part of the patch input, but ignore for the mutation.
  2. Again, I agree that the filter for @id isn’t ideal. You can achieve the same effect as ID with and and or, but it’s awkward. We already have a ticket on the board to improve that - I’ve bumped it into the next sprint. There’s also a major revamp of the docs underway. I’ll make sure there’s more mutation examples in there.
  3. Post examples of where the errors aren’t helping you and I’ll prioritise them to get improved

CosmicPangolin commented :

@MichaelJCompton

Awesome, thanks! Those three places were the ones where I spent the most time digging to clarify errors (interface @id, TypeUpdate shape, and filter shape), but I’ll post specifics on anything else I run across.

Really excited about the progress y’all are making with the graphql api. I’ve literally cut my data repos 80% and business logic 30-40% switching to dgraph from Firestore.

@CosmicPangolin1

Apologies that this issue got missed and was filed again in queryTweets works, but getTweets does not work. We have since fixed it. The fix should be available in master and 20.07.1 release.

2 Likes