RuntimeError [400] Request person.etag

Hello,

i have the following problem with one of my scenarios → see Picture_1.
grafik

Here is the scenario → see Picture_2

The last one (Google Contacts) makes the error. And here the error in detail → see Picture_3.

I’ve already contacted make.com support and they told me I need to clear my browser’s cache. I can solve the problem once, but it keeps coming back.

Task:
Please make an offer to solve the problem so that this error generally no longer occurs in the future or let me know why this error can occur.

Thanks.

Greetings,
Peter

1 Like

This seems weird as I haven’t faced such an issue before, do you have multiple scenarios with Google Contact at the moment? I am not sure whether it will help but try adding a Get a Contact Module before the Update Contact and see if that helps.

If it is a running scenario and if it is okay, then can you also enable Sequential processing
to see and also validate whether you are getting Multiple Webhooks for the same event?

I currently have two scenarios with webhook for Google Contact.

In one scenario, only new contacts are created with the webhook “new contact”. In the second scenario - which causes the problem - the webhook “contact_updated” is used. These two scenarios should therefore not influence each other.

What do you mean because of the further module “Get a Contact”. Which parameters do you think i should check in this module?

The problem should be with make.com, as this happens quite often according to our own research. To solve the problem, the browser cache must be cleared continuously. However, this cannot be a permanent solution.

This is a Runtime Error where requested person.etag is different than the current person.etag (logically). This error occurs mainly when the contact gets changed and so the current HTTP request etag gets conflicting , so it is not letting you perform further actions until you refresh that contact in a new request.

Hi !

I have been struggling with the exact same problem for the past few days and your posts are the only thing I can find on the internet about it.

According to my own trial and error, this error happens to me when I update different parts of a contact several times in a row. And it is very inconsistent, sometimes it happens, sometimes not. My guess is also that something is badly coded in the Make.com Google Contacts module that does not update the If-Match header with the correct etag, although some things still do not make sense with that explanation alone :

  • It still fails if I add a Get contact bubble before the next Update contact, even adding a 5s sleep.
    → My guess is that Make.com’s code behind the scenes does not use the etag in the response to update the If-Match header in further requests
  • Why is it not failing consistently ?
    → My guess is the processing speed on Google’s APIs end is not always the same, and/or that their etag does not always change with an update (which would not comply with the etag specs), and/or TOTAL MYSTERY :flushed:
  • Where does the initial etag come from when the first module of the scenario is an Update contact bubble ?
    → My guess is that, only when the Update contact bubble is first, the module will first do a Get call first on the contact to get the correct etag. I think they have to do it because the People API’s updateContact method does not allow a missing etag.

I have to do multiple updates because the Update contact module does not allow you to handle contacts that may or may not have phone number, email, address, urls… Either you always add them, or never : if one is missing, the entire update fails. Other parameters like birth date, family name etc… Are fine because they do not make the request fail if missing, only the object ones like emails, addresses etc… Do.

The solution I found and have yet to test is to use the Make API call module to craft my own request by hand. The other advantage is that this way I can do all of my 5 updates in 1 operation instead of 5 :v: And if this one fails sometimes too, I can use the Retry method, which I would add once but not 5 times.

I am just curious, why are you mentioning the browser’s cache ? If I understand Make correctly, the actual requests to Google’s People API are made from Make.com’s servers, so there is no way that clearing your browser’s cache would have an effect ? Are you sure it does have an effect for you ? If so, I will deeply question my understanding of how Make.com works, and it would surprise me that Make.com would send the necessary auth tokens to our browsers. If I understand correctly, you would have to clear Make.com’s server’s cache, which I don’t think you can.

@Thomas_de_Beauchene

Thank you for your detailed reply.
So far I have not been able to consciously reproduce the error and therefore this error is not reasonable to track. This seems to be consistent with their experience.

The fact is that after clearing the browser cache I have no problems for an indefinite period of time and then the problem starts again with the error message. If I don’t clear the browser cache then I have the error multiple times a day.

The idea of clearing the browser cache was suggested to me by make.com support. Regardless of that, I described the error to a specialist and he also said to delete the cache.

Conclusion:
I have now contacted the make.com support again and asked them to suggest a reasonable solution. As soon as I have feedback I will post it here.

I receive the following answere from the make.com support:

This error is directly coming from “google Contacts” and the error code is 400, which is a client error status code indicating that the client’s request was invalid or could not be processed by the server. If the data that you’re attempting to retrieve has been updated since the last time you cached it, you’re likely to receive this error. You can resolve this issue by removing any locally stored data associated with the person you are trying to retrieve from your computer. You will be able to ensure that you always get the most recent data if you follow this method. I would also suggest that you clear the cache of your browser and retry the scenario running. In case the problem persists, I have also attached a copy of the error log in order to reach out to Google Support.

Here the problem might lie with make.com. I’ve never had any issues like this with Zapier in the past. And what I don’t understand either, if I have closed my browser and my computer is turned off, then this error still occurs.

I have worked around this problem by using the Make an API call Google Contacts module and now I can tell you what the problem is with Make’s code, or at least with the requests that they are sending behind the scenes.

The People API’s updateContact method documentation is pretty clear and so are my tests : you have to include an etag in the request body (not HTTP headers, request body) or the request will fail with error

[400] Request must set person.etag or person.metadata.sources.etag for the source that is being updated.

Which tells me that they always include the etag in the Update Contact request, but somehow they are getting the wrong one. It is not clear how and how it might or might not be related to the browser’s cache, but you have to use the Make an API call to be able to set the right etag and the request to always succeed (minus the occasional 500 error as this entire API seems pretty wonky).

Here is an example working payload, with the required etag field :

{
  "etag": "%EiQBAgMFBgcICQoLD12341234BUWGR8hIiMkJSYnLjQ1Nz0+P0AaBAECBQciDG1jZ2g4UVM2cUhzPQ==",
  "names": [
    {
      "givenName": "Blablabla SOMENAME",
      "familyName": ""
    }
  ],
  "genders": [
    {

      "value": "male",
      "addressMeAs": "he/him"
 
   }
  ],
  "occupations": [
    {
      "value": "Tayste Occupation"
    }
  ],
  "emailAddresses": [
    {
      "value": "blablabla@bla.com",
      "type": "work",
      "displayName": "Tayste Display Name"
    }
  ],
  "addresses": [
    {
      "streetAddress": "123 Some address 12345 SOMECITY",      "country": "Italy",
      "type": "work"
    }
  ],
  "organizations": [
    {
      "name": "Blablabla"
    }
  ],
  "urls": [
    {
      "value": "https://www.blablabla.it/en/",
      "type": "work"
    },
    {
      "value": "https://airtable.com/blablabla",
      "type": "profile"
    }
  ],
  "userDefined": [
    {
      "key": "Gender",
      "value": " ♂️ "
    }
  ]
}

Here is an example of my own Update contact node using Make an API call, as an example that you can copy in your scenario.

{
    "subflows": [
        {
            "flow": [
                {
                    "id": 111,
                    "module": "google-contacts:makeApiCall",
                    "version": 4,
                    "parameters": {
                        "__IMTCONN__": 592193
                    },
                    "mapper": {
                        "qs": [
                            {
                                "key": "updatePersonFields",
                                "value": "names,genders,occupations,phoneNumbers,emailAddresses,addresses,organizations,urls,biographies,userDefined"
                            }
                        ],
                        "url": "/v1/people/{{43.id}}:updateContact",
                        "body": "{\n  \"etag\": \"{{43.etag}}\",\n  \"names\": [\n    {\n      \"givenName\": \"{{1.`First name`}}\",\n      \"familyName\": \"{{1.`Last name`}}\"\n    }\n  ],\n  \"genders\": [\n    {\n{{switch(1.Gender; \" ♂️ \"; \"\n      \"\"value\"\": \"\"male\"\",\n      \"\"addressMeAs\"\": \"\"he/him\"\"\n\"; \" ♀️ \"; \"\n      \"\"value\"\": \"\"female\"\",\n      \"\"addressMeAs\"\": \"\"she/her\"\"\n\"; \"LGBTQIA+\"; \"\n      \"\"value\"\": \"\"N/A\"\",\n      \"\"addressMeAs\"\": \"\"they/them\"\"\n\"; \"\n      \"\"value\"\": \"\"unspecified\"\",\n      \"\"addressMeAs\"\": \"\"they/them\"\"\n\")}} \n   }\n  ],\n  \"occupations\": [\n    {\n      \"value\": \"Tayste Occupation\"\n    }\n  ]{{if(1.Mobile | 1.Phone; \",\n  \"\"phoneNumbers\"\": [\n\" + if(1.Mobile; \"\n    {\n      \"\"value\"\": \"\"\" + 1.Mobile + \"\"\",\n      \"\"type\"\": \"\"mobile\"\"\n    }\" + if(1.Mobile & 1.Phone; \",\")) + if(1.Phone; \"\n    {\n      \"\"value\"\": \"\"\" + 1.Phone + \"\"\",\n      \"\"type\"\": \"\"work\"\"\n    }\n\") + \"\n  ]\")}}{{if(1.Email; \",\n  \"\"emailAddresses\"\": [\n    {\n      \"\"value\"\": \"\"\" + 1.Email + \"\"\",\n      \"\"type\"\": \"\"work\"\",\n      \"\"displayName\"\": \"\"Tayste Display Name\"\"\n    }\n  ]\")}}{{if(6.Address | 6.Country; \",\n  \"\"addresses\"\": [\n    {\n\" + if(6.Address; \"      \"\"streetAddress\"\": \"\"\" + 6.Address + \"\"\",\") + if(6.Country; \"      \"\"country\"\": \"\"\" + 6.Country + \"\"\",\") + \"\n      \"\"type\"\": \"\"work\"\"\n    }\n  ]\")}},\n  \"organizations\": [\n    {\n      \"name\": \"{{6.Name}}\"{{if(1.`Job title` + \",\n      \"\"title\"\": \"\"\" + 1.`Job title` + \"\"\"\")}}\n    }\n  ],\n  \"urls\": [\n{{if(6.Website; \"    {\n      \"\"value\"\": \"\"\" + 6.Website + \"\"\",\n      \"\"type\"\": \"\"work\"\"\n    },\")}}{{if(1.Linkedin; \"\n    {\n      \"\"value\"\": \"\"\" + 1.Linkedin + \"\"\",\n      \"\"type\"\": \"\"linkedin\"\"\n    },\")}}\n    {\n      \"value\": \"https://airtable.com/appNlv21RrpAGmsyV/tbl8dODvN066m2wIc/viwMZB2q25fAGka9v/{{1.id}}\",\n      \"type\": \"profile\"\n    }\n  ]{{if(1.Notes; \",\n  \"\"biographies\"\": [\n    {\n      \"\"value\"\": \"\"\" + 1.Notes + \"\"\",\n      \"\"contentType\"\": \"\"TEXT_PLAIN\"\"\n    }\n  ]\")}}{{if(1.Gender; \",\n  \"\"userDefined\"\": [\n    {\n      \"\"key\"\": \"\"Gender\"\",\n      \"\"value\"\": \"\"\" + 1.Gender + \"\"\"\n    }\n  ]\")}}\n}",
                        "method": "PATCH",
                        "headers": [
                            {
                                "key": "Content-Type",
                                "value": "application/json"
                            }
                        ]
                    },
                    "metadata": {
                        "designer": {
                            "x": 1200,
                            "y": 300,
                            "name": "Update Contact"
                        },
                        "restore": {
                            "expect": {
                                "qs": {
                                    "mode": "chose",
                                    "items": [
                                        null
                                    ]
                                },
                                "method": {
                                    "mode": "chose",
                                    "label": "PATCH"
                                },
                                "headers": {
                                    "mode": "chose",
                                    "items": [
                                        null
                                    ]
                                }
                            },
                            "parameters": {
                                "__IMTCONN__": {
                                    "data": {
                                        "scoped": "true",
                                        "connection": "google"
                                    },
                                    "label": "Flowrates Thomas Google"
                                }
                            }
                        },
                        "parameters": [
                            {
                                "name": "__IMTCONN__",
                                "type": "account:google",
                                "label": "Connection",
                                "required": true
                            }
                        ],
                        "expect": [
                            {
                                "name": "url",
                                "type": "text",
                                "label": "URL",
                                "required": true
                            },
                            {
                                "name": "method",
                                "type": "select",
                                "label": "Method",
                                "required": true,
                                "validate": {
                                    "enum": [
                                        "GET",
                                        "POST",
                                        "PUT",
                                        "PATCH",
                                        "DELETE"
                                    ]
                                }
                            },
                            {
                                "name": "headers",
                                "spec": [
                                    {
                                        "name": "key",
                                        "type": "text",
                                        "label": "Key"
                                    },
                                    {
                                        "name": "value",
                                        "type": "text",
                                        "label": "Value"
                                    }
                                ],
                                "type": "array",
                                "label": "Headers"
                            },
                            {
                                "name": "qs",
                                "spec": [
                                    {
                                        "name": "key",
                                        "type": "text",
                                        "label": "Key"
                                    },
                                    {
                                        "name": "value",
                                        "type": "text",
                                        "label": "Value"
                                    }
                                ],
                                "type": "array",
                                "label": "Query String"
                            },
                            {
                                "name": "body",
                                "type": "any",
                                "label": "Body"
                            }
                        ]
                    }
                }
            ]
        }
    ],
    "metadata": {
        "version": 1
    }
}

Note that if you want to add a profile picture it will have to be in a separate request, although this one is much more simple.

@Thomas_de_Beauchene

Have you shared this information with make.com support? Is there an official statement on whether this issue will be resolved by make.com in the future?

Thanks also for your detailed answer. Unfortunately, I don’t have that much experience in working with API interfaces, so I don’t know how to embed this code in my scenario.

But maybe you can also give me feedback if you got any feedback from make.com support?

Thanks!

My 2nd snippet is what you get in your clipboard when you right click a bubble and click copy module, so I guess you just copy this text in your clipboard and then right click and paste in your scenario.

What is inside the bubble is a good base that you can modify, as I already read the docs, understood them and implemented the part that you need coding background for for you. You shouldn’t need coding background for the rest - adapting existing code to your own purpose is usually how you start :wink:

I did not contact or share any of that with Make support as my own problem is solved, but you are welcome to if you are already in touch with them. Actually I would love to have access to the code of their modules, as so many of them have so many obvious bugs that I could easily fix.

Hello @vantage :wave:

just wanted to jump in and ask whether you tried @Thomas_de_Beauchene’s suggestion and if they worked for you.

If yes, would you mind marking his response as a solution? This way our community stays organized for other users to look for possible solutions to their problems.

Thank you :sunny: