Repository navigation
Catch InvalidArgumentException while GoogleAdsException expected when mutate #852
Description
### Problem Overview
I currently frequently met the cases that when I am using GoogleAdsServiceClient.mutate method submitting list of MutateOperations, I caught InvalidArgumentException instead of GoogleAdsException.
https://cloud.google.com/java/docs/reference/gax/latest/com.google.api.gax.rpc.InvalidArgumentException
And the actual invalid info like POLICY_FINDING from textual asset, Duplication of campaign name or those should have thrown GoogleAdsException as expected.
By following the guidelines in GoogleAds Docs, I am able to solve and extract error details from GoogleAdsException class type. But InvalidArgumentException seems have a different structure while I could only print the error message from InvalidArgumentException.getErrorDetails().toString()
### Latest Sample Error message:
[Google] Mutate - InvalidArgumentException INVALID_ARGUMENT: ErrorDetails{rawErrorMessages=[type_url: "type.googleapis.com/google.ads.googleads.v19.errors.GoogleAdsFailure"
value: "\n\306\001\n\003\240\004\002\022eThe resource has been disapproved since the policy summary includes policy topics of type PROHIBITED."@\022\025\n\021mutate_operations\030\000\022\027\n\025ad_group_ad_operation\022\b\n\006create\022\004\n\002ad*\026\032\024\n\022\020\002*\016CAPITALIZATION\nn\n\0028\003\022\027Resource was not found."O\022\025\n\021mutate_operations\030\001\022\035\n\033ad_group_ad_label_operation\022\b\n\006create\022\r\n\vad_group_ad\022\026TUNgUBK4VIVCzBjU5a3HJA"
]}
### Request Details
Click to expand full request/response detail
FAILURE REQUEST DETAIL.
Request
MethodName: google.ads.googleads.v19.services.GoogleAdsService/Mutate
Endpoint: googleads.googleapis.com:443
Headers: {developer-token=REDACTED, login-customer-id=8984689079, x-goog-api-client=gl-java/17.0.10__Oracle-Corporation gccl/36.1.0--protobuf-3 gapic/36.1.0 gax/2.63.1 grpc/1.70.0 protobuf/3}
Body: customer_id: "4600599411"
mutate_operations {
ad_group_ad_operation {
create {
resource_name: "customers/4600599411/adGroupAds/183048342616~-1"
status: ENABLED
ad {
responsive_search_ad {
headlines {
text: "Essenciais para Volta \303\240s Aulas"
}
headlines {
text: "Loja completa: Volta \303\240s aulas"
}
headlines {
text: "At\303\251 90%OFF em material escolar"
}
headlines {
text: "Ofertas Volta \303\240s Aulas"
}
headlines {
text: "Promo\303\247\303\243o Volta \303\240s Aulas"
}
headlines {
text: "Essenciais para a escola"
}
headlines {
text: "Consiga seu Passe de Estilo"
}
headlines {
text: "Estilo escolar com at\303\251 90% OFF"
}
headlines {
text: "500mil looks p/ volta \303\240s aulas"
}
headlines {
text: "Material escolar"
}
headlines {
text: "Lista de material escolar"
}
headlines {
text: "Economize na Volta \303\240s Aulas"
}
headlines {
text: "Arrase na volta \303\240s aulas"
}
headlines {
text: "Estilo escolar em sess\303\243o"
}
descriptions {
text: "At\303\251 90% OFF em +500 mil best sellers da SHEIN \342\200\224 sua loja completa pra volta \303\240s aulas!"
}
descriptions {
text: "Comece o ano letivo com itens essenciais com at\303\251 90% de desconto!"
}
descriptions {
text: "Arrase com estilo com a SHEIN\342\200\224seu destino \303\272nico para a volta \303\240s aulas!"
}
descriptions {
text: "Consiga o estilo com at\303\251 90% off em +de 500 mil itens essenciais para sua volta \303\240s aulas!"
}
}
final_urls: "https://shein.com/onelink/14/4uxqtmdnv0ny?keyword={keyword}"
name: "BR-PC-\345\223\201\347\211\214\350\257\215-20250721-91d460a8f8-adhub00009"
}
ad_group: "customers/4600599411/adGroups/183048342616"
}
}
}
mutate_operations {
ad_group_ad_label_operation {
create {
ad_group_ad: "customers/4600599411/adGroupAds/183048342616~-1"
label: "customers/4600599411/labels/22052432566"
}
}
}
response_content_type: MUTABLE_RESOURCE
Response
Headers: Metadata(content-type=application/grpc,request-id=TUNgUBK4VIVCzBjU5a3HJA,date=Thu, 17 Jul 2025 07:25:28 GMT,alt-svc=h3=":443"; ma=2592000,h3-29=":443"; ma=2592000)
Body: null
Failure message: errors {
error_code {
policy_finding_error: POLICY_FINDING
}
message: "The resource has been disapproved since the policy summary includes policy topics of type PROHIBITED."
location {
field_path_elements {
field_name: "mutate_operations"
index: 0
}
field_path_elements {
field_name: "ad_group_ad_operation"
}
field_path_elements {
field_name: "create"
}
field_path_elements {
field_name: "ad"
}
}
details {
policy_finding_details {
policy_topic_entries {
type: PROHIBITED
topic: "CAPITALIZATION"
}
}
}
}
errors {
error_code {
mutate_error: RESOURCE_NOT_FOUND
}
message: "Resource was not found."
location {
field_path_elements {
field_name: "mutate_operations"
index: 1
}
field_path_elements {
field_name: "ad_group_ad_label_operation"
}
field_path_elements {
field_name: "create"
}
field_path_elements {
field_name: "ad_group_ad"
}
}
}
request_id: "TUNgUBK4VIVCzBjU5a3HJA"
Status: Status{code=INVALID_ARGUMENT, description=Request contains an invalid argument., cause=null}.
Stack Trace
Expand to view full stack trace
[Google] Campaign - Exception occurred during creating ad_group_ad [2497797]:
com.google.api.gax.rpc.InvalidArgumentException: io.grpc.StatusRuntimeException: INVALID_ARGUMENT: Request contains an invalid argument.
at com.google.api.gax.rpc.ApiExceptionFactory.createException(ApiExceptionFactory.java:92)
at com.google.api.gax.grpc.GrpcApiExceptionFactory.create(GrpcApiExceptionFactory.java:98)
at com.google.api.gax.grpc.GrpcApiExceptionFactory.create(GrpcApiExceptionFactory.java:66)
at com.google.api.gax.grpc.GrpcExceptionCallable$ExceptionTransformingFuture.onFailure(GrpcExceptionCallable.java:97)
at com.google.api.core.ApiFutures$1.onFailure(ApiFutures.java:84)
at com.google.common.util.concurrent.Futures$CallbackListener.run(Futures.java:1132)
at com.google.common.util.concurrent.DirectExecutor.execute(DirectExecutor.java:31)
at com.google.common.util.concurrent.AbstractFuture.executeListener(AbstractFuture.java:1307)
at com.google.common.util.concurrent.AbstractFuture.complete(AbstractFuture.java:1070)
at com.google.common.util.concurrent.AbstractFuture.setException(AbstractFuture.java:819)
at io.grpc.stub.ClientCalls$GrpcFuture.setException(ClientCalls.java:651)
at io.grpc.stub.ClientCalls$UnaryStreamToFuture.onClose(ClientCalls.java:621)
at io.grpc.PartialForwardingClientCallListener.onClose(PartialForwardingClientCallListener.java:39)
at io.grpc.ForwardingClientCallListener.onClose(ForwardingClientCallListener.java:23)
at io.grpc.ForwardingClientCallListener$SimpleForwardingClientCallListener.onClose(ForwardingClientCallListener.java:40)
at com.google.api.gax.grpc.ChannelPool$ReleasingClientCall$1.onClose(ChannelPool.java:569)
at io.grpc.PartialForwardingClientCallListener.onClose(PartialForwardingClientCallListener.java:39)
at io.grpc.ForwardingClientCallListener.onClose(ForwardingClientCallListener.java:23)
at io.grpc.ForwardingClientCallListener$SimpleForwardingClientCallListener.onClose(ForwardingClientCallListener.java:40)
at com.google.ads.googleads.lib.logging.LoggingInterceptor$1$1.onClose(LoggingInterceptor.java:113)
at io.grpc.PartialForwardingClientCallListener.onClose(PartialForwardingClientCallListener.java:39)
at io.grpc.ForwardingClientCallListener.onClose(ForwardingClientCallListener.java:23)
at io.grpc.ForwardingClientCallListener$SimpleForwardingClientCallListener.onClose(ForwardingClientCallListener.java:40)
at com.google.api.gax.grpc.GrpcLoggingInterceptor$1$1.onClose(GrpcLoggingInterceptor.java:98)
at io.grpc.internal.DelayedClientCall$DelayedListener$3.run(DelayedClientCall.java:489)
at io.grpc.internal.DelayedClientCall$DelayedListener.delayOrExecute(DelayedClientCall.java:453)
at io.grpc.internal.DelayedClientCall$DelayedListener.onClose(DelayedClientCall.java:486)
at io.grpc.internal.ClientCallImpl.closeObserver(ClientCallImpl.java:564)
at io.grpc.internal.ClientCallImpl.access$100(ClientCallImpl.java:72)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInternal(ClientCallImpl.java:729)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInContext(ClientCallImpl.java:710)
at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37)
at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:133)
at com.alibaba.ttl.TtlRunnable.run(TtlRunnable.java:60)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:842)
Suppressed: com.google.api.gax.rpc.AsyncTaskException: Asynchronous task failed
at com.google.api.gax.rpc.ApiExceptions.callAndTranslateApiException(ApiExceptions.java:57)
at com.google.api.gax.rpc.UnaryCallable.call(UnaryCallable.java:112)
at com.google.ads.googleads.v19.services.GoogleAdsServiceClient.mutate(GoogleAdsServiceClient.java:596)
### Questions
Is there any solutions to avoid getting InvalidArgumentException or convert InvalidArgumentException data to GoogleAdsException?
Activity
sarahcaseybot commentedon Jul 17, 2025
Hi,
Have you tried updating your catch block to specifically catch GoogleAdsExceptions?
Thanks,
Sarah, Google Ads API Team
JiangYisong-96 commentedon Jul 18, 2025
Hi,
Thanks for your reply! I used to try catch specific type of Exceptions and the result was the same.
If there is a case that GoogleAdsException was token place by InvalidArgumentException?
I also got GoogleAdsExceptions at the same place with the stack track:
[Google] Campaign - GoogleAdsException occurred during creating campaign 554383:
com.google.ads.googleads.v19.errors.GoogleAdsException: errors {
error_code {
campaign_error: DUPLICATE_CAMPAIGN_NAME
}
message: "Trying to modify the name of an active or paused campaign, where the name is already assigned to another active or paused campaign."
trigger {
string_value: "554383-US-Android-UAC-20250717-b9ba20388c-adhub00416"
}
location {
field_path_elements {
field_name: "mutate_operations"
index: 1
}
field_path_elements {
field_name: "campaign_operation"
}
field_path_elements {
field_name: "create"
}
field_path_elements {
field_name: "name"
}
}
}
errors {
error_code {
mutate_error: RESOURCE_NOT_FOUND
}
... RESOURCE_NOT_FOUND ignored...
}
request_id: "45Vu4aRCyeDM76hKZ-_PQQ"
sarahcaseybot commentedon Jul 18, 2025
Hi,
This is not a case where the GoogleAdsException is being replaced by the InvalidArgumentException as the InvalidArgumentException is simply a more generic version of the same exception.
In Java, you must catch the most specific exception type first. If you have a catch block for a general exception type like
ExceptionorApiExceptionplaced before your catch block forGoogleAdsExceptionthen your general block will always execute first.Please ensure your code is structured to catch the
GoogleAdsExceptionbefore any broader exception types.Thanks,
Sarah, Google Ads API Team
JiangYisong-96 commentedon Jul 21, 2025
Hi Sarah,
I tried to distinguished the Exception type and try to catch the specific GoogleAdsException in my code block.
But you can find the Stack Trace in my first post content, where it indicates the type of Exception is InvalidArgumentException, which could not be caught by GoogleAdsException catch block.
And the error details was actually a GoogleAdsException.
The main challenge is that the API is returning an InvalidArgumentException instead of a GoogleAdsException for POLICY_FINDING errors. This makes it difficult to catch and handle these specific errors.
Do you have any recommendations or guidance on how to address this InvalidArgumentException when it is in fact a POLICY_FINDING error?
Thanks & Best Regards,
Yisong
sarahcaseybot commentedon Jul 22, 2025
Hello Yisong,
You could try unpacking the metadata and getting the cause of the thrown exception.
Thanks,
Sarah, Google Ads API Team
JiangYisong-96 commentedon Jul 23, 2025
Hi Sarah,
Big appreciate for your hints! But it may takes some time to test if it works as this InvalidArgumentException occurs at a low frequency. Once it solve my issue I will confirm here.
Thanks & Best Regards,
Yisong
JiangYisong-96 commentedon Aug 5, 2025
Hi Sarah,
We received the error again. But the metadata is empty(null). Here is what I collected:
FAILURE REQUEST DETAIL.
Request
MethodName: google.ads.googleads.v19.services.GoogleAdsService/Mutate
Endpoint: googleads.googleapis.com:443
Headers: {developer-token=REDACTED, login-customer-id=5555, x-goog-api-client=gl-java/17.0.10__Oracle-Corporation gccl/36.1.0--protobuf-3 gapic/36.1.0 gax/2.63.1 grpc/1.70.0 protobuf/3}
Body: customer_id: "555"
mutate_operations {
campaign_budget_operation {
create {
resource_name: "customers/555/campaignBudgets/-1"
delivery_method: STANDARD
name: "6742ec2a-5693-47b0-bc0b-44293ca74794"
amount_micros: 50000000
explicitly_shared: false
}
}
}
m......
}
}
response_content_type: MUTABLE_RESOURCE
Response
Headers: Metadata(content-type=application/grpc,request-id=KNjjA8IZouoSBOq9bEdIRw,date=Tue, 05 Aug 2025 12:06:10 GMT,alt-svc=h3=":443"; ma=2592000,h3-29=":443"; ma=2592000)
Body: null
Failure message: errors {
error_code {
asset_link_error: YOUTUBE_VIDEO_DURATION_NOT_DEFINED
}
message: "The YouTube video referenced in the provided asset has unknown duration. This might be the case for a livestream video or a video being currently uploaded to YouTube. In both cases, the video duration should eventually get resolved."
trigger {
int64_value: 271712702257
}
location {
field_path_elements {
field_name: "mutate_operations"
index: 13
}
field_path_elements {
field_name: "ad_group_ad_operation"
}
field_path_elements {
field_name: "create"
}
field_path_elements {
field_name: "ad"
}
field_path_elements {
field_name: "app_ad"
}
field_path_elements {
field_name: "youtube_videos"
index: 7
}
}
}
request_id: "KNjjA8IZouoSBOq9bEdIRw"
Status: Status{code=INVALID_ARGUMENT, description=Request contains an invalid argument., cause=null}.
[Google] Campaign - Exception occurred during creating campaign 597570:
com.google.api.gax.rpc.InvalidArgumentException: io.grpc.StatusRuntimeException: INVALID_ARGUMENT: Request contains an invalid argument.
at com.google.api.gax.rpc.ApiExceptionFactory.createException(ApiExceptionFactory.java:92)
at com.google.api.gax.grpc.GrpcApiExceptionFactory.create(GrpcApiExceptionFactory.java:98)
at com.google.api.gax.grpc.GrpcApiExceptionFactory.create(GrpcApiExceptionFactory.java:66)
at com.google.api.gax.grpc.GrpcExceptionCallable$ExceptionTransformingFuture.onFailure(GrpcExceptionCallable.java:97)
at com.google.api.core.ApiFutures$1.onFailure(ApiFutures.java:84)
at com.google.common.util.concurrent.Futures$CallbackListener.run(Futures.java:1132)
at com.google.common.util.concurrent.DirectExecutor.execute(DirectExecutor.java:31)
at com.google.common.util.concurrent.AbstractFuture.executeListener(AbstractFuture.java:1307)
at com.google.common.util.concurrent.AbstractFuture.complete(AbstractFuture.java:1070)
at com.google.common.util.concurrent.AbstractFuture.setException(AbstractFuture.java:819)
at io.grpc.stub.ClientCalls$GrpcFuture.setException(ClientCalls.java:651)
at io.grpc.stub.ClientCalls$UnaryStreamToFuture.onClose(ClientCalls.java:621)
at io.grpc.PartialForwardingClientCallListener.onClose(PartialForwardingClientCallListener.java:39)
at io.grpc.ForwardingClientCallListener.onClose(ForwardingClientCallListener.java:23)
at io.grpc.ForwardingClientCallListener$SimpleForwardingClientCallListener.onClose(ForwardingClientCallListener.java:40)
at com.google.api.gax.grpc.ChannelPool$ReleasingClientCall$1.onClose(ChannelPool.java:569)
at io.grpc.PartialForwardingClientCallListener.onClose(PartialForwardingClientCallListener.java:39)
at io.grpc.ForwardingClientCallListener.onClose(ForwardingClientCallListener.java:23)
at io.grpc.ForwardingClientCallListener$SimpleForwardingClientCallListener.onClose(ForwardingClientCallListener.java:40)
at com.google.ads.googleads.lib.logging.LoggingInterceptor$1$1.onClose(LoggingInterceptor.java:113)
at io.grpc.PartialForwardingClientCallListener.onClose(PartialForwardingClientCallListener.java:39)
at io.grpc.ForwardingClientCallListener.onClose(ForwardingClientCallListener.java:23)
at io.grpc.ForwardingClientCallListener$SimpleForwardingClientCallListener.onClose(ForwardingClientCallListener.java:40)
at com.google.api.gax.grpc.GrpcLoggingInterceptor$1$1.onClose(GrpcLoggingInterceptor.java:98)
at io.grpc.internal.DelayedClientCall$DelayedListener$3.run(DelayedClientCall.java:489)
at io.grpc.internal.DelayedClientCall$DelayedListener.delayOrExecute(DelayedClientCall.java:453)
at io.grpc.internal.DelayedClientCall$DelayedListener.onClose(DelayedClientCall.java:486)
at io.grpc.internal.ClientCallImpl.closeObserver(ClientCallImpl.java:564)
at io.grpc.internal.ClientCallImpl.access$100(ClientCallImpl.java:72)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInternal(ClientCallImpl.java:729)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInContext(ClientCallImpl.java:710)
at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37)
at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:133)
at com.alibaba.ttl.TtlRunnable.run(TtlRunnable.java:60)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:842)
Suppressed: com.google.api.gax.rpc.AsyncTaskException: Asynchronous task failed
at com.google.api.gax.rpc.ApiExceptions.callAndTranslateApiException(ApiExceptions.java:57)
at com.google.api.gax.rpc.UnaryCallable.call(UnaryCallable.java:112)
at com.google.ads.googleads.v19.services.GoogleAdsServiceClient.mutate(GoogleAdsServiceClient.java:596)
at c--.google.GoogleAdsBase.batchMutate(GoogleAdsBase.java:322)
at c--.google.GoogleAdsBase.batchMutate(GoogleAdsBase.java:289)
at c--.google.GoogleAdsMutateClient.submitOperations(GoogleAdsMutateClient.java:507)
at c--.google.GoogleAdsMutateClient.batchSubm-tCreation(GoogleAdsMutateClient.java:470)
at c--.google.GoogleAdsMutateClient.processMainContent(GoogleAdsMutateClient.java:391)
--
at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1768)
at cn.dotfashion.soa.sheintracing.concurrent.executor.TracingRunnable.run(TracingRunnable.java:34)
... 4 common frames omitted
Caused by: io.grpc.StatusRuntimeException: INVALID_ARGUMENT: Request contains an invalid argument.
at io.grpc.Status.asRuntimeException(Status.java:532)
... 26 common frames omitted
sarahcaseybot commentedon Aug 6, 2025
Hi Yisong,
Thank you for including your screenshot. Can you please confirm that you have a catch block for a GoogleAdsException before that shown catch block for the InvalidArgumentException?
This library is designed to catch InvalidArgumentExceptions and wrap them in the more useful GoogleAdsException.
JiangYisong-96 commentedon Aug 7, 2025
Hi Sarah,
yes. Here is the part of my code.
Is it possible I missed anything so that the "wrap" mechanism doesn't work.
sarahcaseybot commentedon Aug 11, 2025
Hi Yisong,
Can you try using partial failure with your requests? I believe you may see the GoogleAdsException thrown instead of the InvalidArgumentException if this is a partial failure.
Thanks,
Sarah, Google Ads API Team
JiangYisong-96 commentedon Aug 13, 2025
Hi Sarah,
I understand you re suggesting to allow partial failure in my request. But I actually require atomicity for each batch of mutate requests.
Thanks,
Yisong
sarahcaseybot commentedon Aug 15, 2025
Hi Yisong,
I noticed in your stack trace that it is showing the APIExceptionFactory rather than our typical GoogleAdsException factory. Can you please share how you are creating your service client? Is there someway you may be disabling the GoogleAdsException factory?
Thanks,
Sarah, Google Ads API Team
yanivkrol commentedon Jan 13, 2026
Hi Sarah,
Our team faces the same issue. It suddenly started to happen about half a year ago for INVALID_ARGUMENT:
We have a java 11 application using Google Ads SDK.
Our code relied on working with
com.google.ads.googleads.v18.errors.GoogleAdsExceptionif things were to go wrong. One day out of nowhere, with no library changes, we started gettingcom.google.api.gax.rpc.InvalidArgumentExceptionfor a specific use case instead (creating a conversion action). Obviously this different type breaks our code and doesn't have the amount of data we had to work withGoogleAdsApiException.This behavior started with Ads SDK v18. we tried upgrading these packages (to the noted versions):
but that did not work.
We later upgraded to v20 with:
but that did not work either.
Here is a sample response that causes this exception:
We have the catch block for
GoogleAdsApiExceptionbefore the catch block for generalExceptionsarahcaseybot commentedon Jan 14, 2026
Hello,
I think I may have identified what is causing these issues. I am working on a fix.
Thanks,
Sarah, Google Ads API Team
yanivkrol commentedon Jan 28, 2026
Hi, any update regarding this?
sarahcaseybot commentedon Feb 2, 2026
Hello Yanivkrol,
I am still trying to figure out what the root cause of this issue is. Can you please provide some more information on the error your seeing?
Thanks,
Sarah, Google Ads API Team
yanivkrol commentedon Feb 4, 2026
sarahcaseybot commentedon Feb 6, 2026
Hi Yanivkrol,
Thanks for sharing that code snippet.
I have a theory that the issue is the use of try-with-resources to create and close the ConversionActionServiceClient for every request.
When the client is closed immediately after an exception occurs, it can sever the gRPC connection before the library has finished processing the response trailers. These trailers contain the specific GoogleAdsFailure details needed to generate a GoogleAdsException. When this data is lost due to the client closing too early, the library falls back to throwing the generic InvalidArgumentException.
Could you please try refactoring your code to instantiate the ConversionActionServiceClient once (e.g., as a Singleton) and reuse it across requests without closing it inside this method?
Thanks,
Sarah, Google Ads API Team
yanivkrol commentedon Feb 8, 2026
Hi Sarah,
Thanks, we will try.
But just to note that other exception types are caught well, just for this INVALID_ARGUMENT it seems
yanivkrol commentedon Jul 7, 2026
Any progress?
#871