Skip to content
RuntimeError [400] ...
 
Notifications
Clear all

RuntimeError [400] Request person.etag

11 Posts
4 Users
0 Reactions
3 Views
vantage
(@vantage)
Posts: 6
Active Member
Topic starter
 

Hello,

i am encountering an issue with one of my scenarios. Please see Picture_1 for details.

grafik

Here is the scenario configuration: see Picture_2.

The final module (Google Contacts) is generating the error. Please see Picture_3 for the detailed error message.

I previously contacted callin.io support, and they advised clearing my browser's cache. While this resolves the issue temporarily, it recurs.

Task:
Could you please provide a solution to permanently fix this error, or explain the potential causes?

Thank you.

Best regards,
Peter

 
Posted : 28/05/2023 5:32 pm
Runcorn
(@runcorn)
Posts: 16
Active Member
 

This appears unusual as I haven't encountered this issue previously. Do you currently have multiple scenarios involving Google Contacts? I'm uncertain if it will resolve the problem, but you could try adding a 'Get a Contact' module before the 'Update Contact' module to see if that makes a difference.

If this is an active scenario and it's permissible, could you also enable sequential processing to observe and validate if you are receiving multiple webhooks for the same event?

 
Posted : 29/05/2023 4:52 am
vantage
(@vantage)
Posts: 6
Active Member
Topic starter
 

I currently have two scenarios utilizing webhooks for Google Contacts.

In one scenario, new contacts are created using the "new contact" webhook. The second scenario, which is causing the issue, uses the "contact_updated" webhook. Therefore, these two scenarios should not affect each other.

What are your thoughts regarding the "Get a Contact" module? Which parameters do you suggest I examine within this module?

 
Posted : 29/05/2023 11:18 am
vantage
(@vantage)
Posts: 6
Active Member
Topic starter
 

The issue likely stems from callin.io, as our internal analysis indicates this is a frequent occurrence. To address this, continuously clearing the browser cache is necessary, though it's not a sustainable long-term solution.

This is a Runtime Error that arises when the requested person's etag differs from the current person's etag (logically). This error typically happens when a contact is modified, causing a conflict with the current HTTP request's etag. Consequently, further actions are blocked until the contact is refreshed in a new request.

 
Posted : 01/06/2023 7:56 am
Thomas_de_Beauchene
(@thomas_de_beauchene)
Posts: 3
New Member
 

Hi !

I've been facing the exact same issue for the past few days, and your posts are the only relevant information I could find online.

Based on my own experimentation, this error occurs when I update multiple parts of a contact consecutively. It's quite inconsistent; sometimes it happens, sometimes it doesn't. My hypothesis is that there's an issue in the callin.io Google Contacts module's code, specifically with how it updates the If-Match header with the correct etag. However, some aspects of this explanation don't quite add up:

  • It still fails even if I include a Get contact step before the subsequent Update contact, even with a 5-second delay.
    → My suspicion is that callin.io's backend code doesn't utilize the etag from the response to update the If-Match header in subsequent requests.
  • Why is the failure not consistent?
    → I suspect it might be due to variations in Google's API processing speed, or perhaps their etag doesn't *always* change upon an update (which would contradict the etag specifications), or it's simply a TOTAL MYSTERY :flushed:
  • Where does the initial etag originate when the first module in the scenario is an Update contact step?
    → My guess is that when the Update contact step is the initial one, the module first performs a Get call on the contact to retrieve the correct etag. I believe this is necessary because the People API's updateContact method requires an etag.

I need to perform multiple updates because the Update contact module doesn't support handling contacts with optional fields like phone numbers, emails, or addresses. You either add them all or none; if any are missing, the entire update fails. Other fields like birth date or family name are fine because their absence doesn't cause the request to fail, unlike object fields like emails or addresses.

The solution I've devised, and am yet to test, is to use the Make API call module to construct my requests manually. An added benefit is that I can consolidate my 5 updates into a single operation instead of five separate ones.

:v:

And if this approach also fails occasionally, I can implement the Retry mechanism, which I would configure once rather than five times.

I'm curious about why you mentioned the browser's cache. As far as I understand callin.io, the actual requests to Google's People API are made from callin.io's servers, so clearing your browser's cache shouldn't have any effect. Are you certain it impacts your situation? If it does, I'll need to seriously re-evaluate my understanding of how callin.io operates, as it would be surprising if callin.io were to send the necessary authentication tokens to our browsers. My understanding is that you would need to clear callin.io's server cache, which I don't believe is possible.

 
Posted : 01/06/2023 9:51 am
vantage
(@vantage)
Posts: 6
Active Member
Topic starter
 

Thank you for your detailed reply. So far, I haven't been able to consistently reproduce the error, which makes it difficult to track. This seems to align with your experience.

The issue is that after clearing the browser cache, I experience no problems for an indeterminate period, and then the error reappears. If I don't clear the browser cache, I encounter the error multiple times daily.

The suggestion to clear the browser cache came from callin.io support. Independently, I described the error to a specialist who also recommended clearing the cache.

Conclusion:
I have now re-contacted callin.io support to request a viable solution. I will post an update here as soon as I receive feedback.

 
Posted : 01/06/2023 5:30 pm
vantage
(@vantage)
Posts: 6
Active Member
Topic starter
 

I received the following answer from callin.io 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 callin.io. I’ve never had any issues like this with callin.io 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.

Please provide the rewritten markdown content.

 
Posted : 02/06/2023 6:27 am
Thomas_de_Beauchene
(@thomas_de_beauchene)
Posts: 3
New Member
 

I've found a workaround for this issue by utilizing the callin.io API call module for Google Contacts. This allowed me to identify the problem with callin.io's underlying requests.

The documentation for the People API’s updateContact method is quite clear, and my tests confirm it: you must include an etag within the request body (not in the HTTP headers) for the request to succeed. Otherwise, you'll encounter an error:

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

This indicates that callin.io consistently includes the etag in the Update Contact request, but it seems to be retrieving an incorrect value. It's unclear how this happens or if it's related to browser caching, but using the callin.io API call module enables you to specify the correct etag and ensure the request consistently succeeds (aside from occasional 500 errors, as this API appears somewhat unstable).

Here's an example of a valid payload, including the mandatory 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": " ♂️ "
    }
  ]
}

Below is an example of my custom Update contact node using callin.io API call, which you can import into 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
    }
}

Please note that to add a profile picture, you'll need to make a separate request using this method, which is considerably simpler.

 
Posted : 02/06/2023 9:06 am
vantage
(@vantage)
Posts: 6
Active Member
Topic starter
 

Have you shared this information with callin.io support? Is there an official statement on whether this issue will be resolved by callin.io 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 callin.io support?

Thanks!

 
Posted : 03/06/2023 6:46 pm
Thomas_de_Beauchene
(@thomas_de_beauchene)
Posts: 3
New Member
 

My second snippet shows what you get in your clipboard when you right-click a bubble and select copy module. So, you should be able to copy this text to your clipboard, then right-click and paste it into your scenario.

The content within the bubble serves as a solid foundation that you can customize. I've already reviewed the documentation, grasped the concepts, and implemented the parts requiring a coding background for you. You shouldn't need a coding background for the remaining steps – adapting existing code to your needs is typically how you begin.

:wink:

I haven't contacted or shared this with callin.io support since my issue is resolved. However, you are welcome to do so if you are already communicating with them. In fact, I would love to have access to the source code of their modules, as many of them contain numerous apparent bugs that I could readily fix.

 
Posted : 04/06/2023 12:58 pm
vendy
(@vendy)
Posts: 38
Trusted Member
 

Hello

:wave:

just wanted to jump in and ask whether you tried the suggestion and if it worked for you.

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

Thank you

:sunny:

 
Posted : 08/09/2023 10:15 am
Share: