diff --git a/packages/agent-core-v2/src/app/llmProtocol/errors.ts b/packages/agent-core-v2/src/app/llmProtocol/errors.ts index 9657d6626..a5d8c812c 100644 --- a/packages/agent-core-v2/src/app/llmProtocol/errors.ts +++ b/packages/agent-core-v2/src/app/llmProtocol/errors.ts @@ -136,6 +136,18 @@ export class APIEmptyResponseError extends ChatProviderError { } } +const DETERMINISTIC_PROVIDER_VALIDATION_MESSAGE_PATTERNS = [ + /unsupported media type for base64 image/, + /invalid data url for image/, +] as const; + +function isDeterministicProviderValidationError(error: ChatProviderError): boolean { + const lowerMessage = error.message.toLowerCase(); + return DETERMINISTIC_PROVIDER_VALIDATION_MESSAGE_PATTERNS.some((pattern) => + pattern.test(lowerMessage), + ); +} + export function isRetryableGenerateError(error: unknown): boolean { if (error instanceof APIConnectionError || error instanceof APITimeoutError) { return true; @@ -149,7 +161,9 @@ export function isRetryableGenerateError(error: unknown): boolean { if (error instanceof APIStatusError) { return [408, 409, 429, 500, 502, 503, 504, 529].includes(error.statusCode); } - return error instanceof ChatProviderError; + return ( + error instanceof ChatProviderError && !isDeterministicProviderValidationError(error) + ); } const NETWORK_RE = /network|connection|connect|disconnect|terminated/i; diff --git a/packages/agent-core-v2/test/app/llmProtocol/errors.test.ts b/packages/agent-core-v2/test/app/llmProtocol/errors.test.ts index 634880700..5ffab3d6e 100644 --- a/packages/agent-core-v2/test/app/llmProtocol/errors.test.ts +++ b/packages/agent-core-v2/test/app/llmProtocol/errors.test.ts @@ -193,6 +193,15 @@ describe('isRetryableGenerateError', () => { it('retries an unclassified provider error as a transient fallback', () => { expect(isRetryableGenerateError(new ChatProviderError('upstream failure'))).toBe(true); }); + + it.each([ + ['Invalid data URL for image: data:image/png;base64'], + [ + 'Unsupported media type for base64 image: image/avif, url: data:image/avif;base64,AAAA', + ], + ])('does not retry deterministic provider validation error: %s', (message) => { + expect(isRetryableGenerateError(new ChatProviderError(message))).toBe(false); + }); }); describe('error hierarchy instanceof checks', () => {