Welcome to part 5 of the series of posts that will give tips and tricks on how to deal with SOAP issues. As a SOAP-based web service, AdWords API can be easy to make calls to. At the same time, it can sometimes be difficult to debug the SOAP faults. In our previous episode, we discussed SOAP errors related to failed validations. Today we'll discuss SOAP errors related to syncing errors and concurrent changes. You can find links to our earlier posts here: Part 1, Part 2, Part 3, Part 4.
Syncing Errors
Some of the common ApiErrors are "Missing a required field", "Wrong value for a field", etc. They are often self-explanatory, so it's easy to spot the error. However, two errors are trickier to spot:
- The client asked us to load an entity but no entity with that ID was found. (Error code 5)
- The client does not have permission to perform the requested operation. (Error code 4)
Both these errors occur among developers who store their AdWords campaigns, ads, etc. in a local database. While storing your campaigns and ads in local database helps to boost performance in your application (and at times help integration with other campaign management systems), your local database might be out of sync with your AdWords account for several reasons, which would cause these errors.
Common causes of your database being out of sync with your account are that the client updated some campaigns using the AdWords website, or that you have a bug in the code that's inserting the wrong records into your local database.
Both the ApiErrors mentioned above take more specific forms, and the detail, field, and trigger properties of the ApiError node should help you find out the cause behind the issue. For example, the following SOAP fault was generated while trying to update a Campaign that does not exist (Campaign ID: 0):
<soapenv:Body>
<soapenv:Fault>
<faultcode>soapenv:Server.userException</faultcode>
<faultstring>One or more input elements failed validation.</faultstring>
<detail>
<ns1:fault xmlns:ns1="https://adwords.google.com/api/adwords/v12">
<ns1:code>122</ns1:code>
<ns1:message>One or more input elements failed validation.</ns1:message>
<ns1:errors>
<ns1:index>0</ns1:index>
<ns1:field>campaignId</ns1:field>
<ns1:trigger>0</ns1:trigger>
<ns1:code>5</ns1:code>
<ns1:isExemptable>false</ns1:isExemptable>
<ns1:detail>No Campaign with this ID was found.</ns1:detail>
</ns1:errors>
</ns1:fault>
</detail>
</soapenv:Fault>
</soapenv:Body>
Note how the error took a specific form (Error code = 5, detail = No campaign with this id was found, field = campaignId, trigger = 0).
<soapenv:Fault>
<faultcode>soapenv:Server.userException</faultcode>
<faultstring>One or more input elements failed validation.</faultstring>
<detail>
<ns1:fault xmlns:ns1="https://adwords.google.com/api/adwords/v12">
<ns1:code>122</ns1:code>
<ns1:message>One or more input elements failed validation.</ns1:message>
<ns1:errors>
<ns1:index>0</ns1:index>
<ns1:field>campaignId</ns1:field>
<ns1:trigger>0</ns1:trigger>
<ns1:code>5</ns1:code>
<ns1:isExemptable>false</ns1:isExemptable>
<ns1:detail>No Campaign with this ID was found.</ns1:detail>
</ns1:errors>
</ns1:fault>
</detail>
</soapenv:Fault>
</soapenv:Body>
Note how the error took a specific form (Error code = 5, detail = No campaign with this id was found, field = campaignId, trigger = 0).
Similarly, the SOAP fault shown below was generated while trying to retrieve a Campaign (Campaign ID : 111111) that my MCC doesn't have access to.
<soapenv:Body>
<soapenv:Fault>
<faultcode>soapenv:Server.userException</faultcode>
<faultstring>Either this object does not exist, or this user does not have permission to access it.</faultstring>
<detail>
<ns1:fault xmlns:ns1="https://adwords.google.com/api/adwords/v12">
<ns1:code>4</ns1:code>
<ns1:message>Either this object does not exist, or this user does not have permission to access it.</ns1:message>
<ns1:trigger>111111</ns1:trigger>
</ns1:fault>
</detail>
</soapenv:Fault>
</soapenv:Body>
<soapenv:Fault>
<faultcode>soapenv:Server.userException</faultcode>
<faultstring>Either this object does not exist, or this user does not have permission to access it.</faultstring>
<detail>
<ns1:fault xmlns:ns1="https://adwords.google.com/api/adwords/v12">
<ns1:code>4</ns1:code>
<ns1:message>Either this object does not exist, or this user does not have permission to access it.</ns1:message>
<ns1:trigger>111111</ns1:trigger>
</ns1:fault>
</detail>
</soapenv:Fault>
</soapenv:Body>
Concurrent Changes
Finally, if you are writing multithreaded applications, or if multiple persons are using your application at the same time, you may come across the error "The Attempted modification failed due to changes made concurrently by another agent or user. (Error code 58)." To avoid this error, make sure your applications are properly synchronized, so that no two threads/instances of your application modifies the same campaign, ad group, ad, etc. at the same time.
You could also run into this error if two programs are modifying the same campaign, ad group or ad at the same time. For example, you could run into this error if 2 people are modifying the same campaign, ad, etc. using the AdWords Front End and AdWords Editor, or even 2 instances of your Application.
Debugging SOAP faults can be frustrating sometimes. We hope these tips will help you in figuring out common issues and save time for something that is more fun -- coding!
--Anash Oommen, AdWords API Team