From b59ea0e3f37fea52b94fb6fb88f5f192e87bc9d0 Mon Sep 17 00:00:00 2001 From: {Suksham-sharma} Date: Tue, 27 Jan 2026 22:21:51 +0530 Subject: [PATCH] fix: prevent infinite retry loop for images exceeding 5MB - Change MAX_IMAGE_BYTES from 6MB to 5MB to match Anthropic API limit - Add isImageSizeError() to detect image size errors from API - Handle image size errors with user-friendly message instead of retry - Prevent failover for image size errors (not retriable) Fixes #2271 --- src/agents/pi-embedded-helpers.ts | 1 + src/agents/pi-embedded-helpers/errors.ts | 7 +++++++ src/agents/pi-embedded-runner/run.ts | 24 ++++++++++++++++++++++++ src/agents/pi-embedded-runner/types.ts | 2 +- src/media/constants.ts | 2 +- 5 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/agents/pi-embedded-helpers.ts b/src/agents/pi-embedded-helpers.ts index 6f6bb474f0..4aed2d0479 100644 --- a/src/agents/pi-embedded-helpers.ts +++ b/src/agents/pi-embedded-helpers.ts @@ -23,6 +23,7 @@ export { isFailoverAssistantError, isFailoverErrorMessage, isImageDimensionErrorMessage, + isImageSizeError, isOverloadedErrorMessage, isRawApiErrorPayload, isRateLimitAssistantError, diff --git a/src/agents/pi-embedded-helpers/errors.ts b/src/agents/pi-embedded-helpers/errors.ts index d6e33f9249..bad476176e 100644 --- a/src/agents/pi-embedded-helpers/errors.ts +++ b/src/agents/pi-embedded-helpers/errors.ts @@ -467,6 +467,12 @@ export function isImageDimensionErrorMessage(raw: string): boolean { return Boolean(parseImageDimensionError(raw)); } +export function isImageSizeError(errorMessage?: string): boolean { + if (!errorMessage) return false; + const lower = errorMessage.toLowerCase(); + return lower.includes("image exceeds") && lower.includes("mb"); +} + export function isCloudCodeAssistFormatError(raw: string): boolean { return !isImageDimensionErrorMessage(raw) && matchesErrorPatterns(raw, ERROR_PATTERNS.format); } @@ -478,6 +484,7 @@ export function isAuthAssistantError(msg: AssistantMessage | undefined): boolean export function classifyFailoverReason(raw: string): FailoverReason | null { if (isImageDimensionErrorMessage(raw)) return null; + if (isImageSizeError(raw)) return null; if (isRateLimitErrorMessage(raw)) return "rate_limit"; if (isOverloadedErrorMessage(raw)) return "rate_limit"; if (isCloudCodeAssistFormatError(raw)) return "format"; diff --git a/src/agents/pi-embedded-runner/run.ts b/src/agents/pi-embedded-runner/run.ts index 69eb1514a5..006172e14b 100644 --- a/src/agents/pi-embedded-runner/run.ts +++ b/src/agents/pi-embedded-runner/run.ts @@ -34,6 +34,7 @@ import { isContextOverflowError, isFailoverAssistantError, isFailoverErrorMessage, + isImageSizeError, parseImageDimensionError, isRateLimitAssistantError, isTimeoutErrorMessage, @@ -440,6 +441,29 @@ export async function runEmbeddedPiAgent( }, }; } + // Handle image size errors with a user-friendly message (no retry needed) + if (isImageSizeError(errorText)) { + return { + payloads: [ + { + text: + "Image too large for the model (max 5MB). " + + "Please compress or resize the image and try again.", + isError: true, + }, + ], + meta: { + durationMs: Date.now() - started, + agentMeta: { + sessionId: sessionIdUsed, + provider, + model: model.id, + }, + systemPromptReport: attempt.systemPromptReport, + error: { kind: "image_size", message: errorText }, + }, + }; + } const promptFailoverReason = classifyFailoverReason(errorText); if (promptFailoverReason && promptFailoverReason !== "timeout" && lastProfileId) { await markAuthProfileFailure({ diff --git a/src/agents/pi-embedded-runner/types.ts b/src/agents/pi-embedded-runner/types.ts index 4be395bce7..27ccfa64ea 100644 --- a/src/agents/pi-embedded-runner/types.ts +++ b/src/agents/pi-embedded-runner/types.ts @@ -20,7 +20,7 @@ export type EmbeddedPiRunMeta = { aborted?: boolean; systemPromptReport?: SessionSystemPromptReport; error?: { - kind: "context_overflow" | "compaction_failure" | "role_ordering"; + kind: "context_overflow" | "compaction_failure" | "role_ordering" | "image_size"; message: string; }; /** Stop reason for the agent run (e.g., "completed", "tool_calls"). */ diff --git a/src/media/constants.ts b/src/media/constants.ts index e74ac69343..8577b6d20c 100644 --- a/src/media/constants.ts +++ b/src/media/constants.ts @@ -1,4 +1,4 @@ -export const MAX_IMAGE_BYTES = 6 * 1024 * 1024; // 6MB +export const MAX_IMAGE_BYTES = 5 * 1024 * 1024; // 5MB (Anthropic API limit) export const MAX_AUDIO_BYTES = 16 * 1024 * 1024; // 16MB export const MAX_VIDEO_BYTES = 16 * 1024 * 1024; // 16MB export const MAX_DOCUMENT_BYTES = 100 * 1024 * 1024; // 100MB