Skip to content

Commit ad9174a

Browse files
committed
AIX: request too large: broaden Vercel explanation
1 parent 433a54a commit ad9174a

4 files changed

Lines changed: 25 additions & 10 deletions

File tree

src/apps/chat/components/message/fragments-content/BlockPartError_RequestExceeded.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Alert, Box, FormHelperText, Switch } from '@mui/joy';
44
import WarningRoundedIcon from '@mui/icons-material/WarningRounded';
55

66
import type { ContentScaling } from '~/common/app.theme';
7+
import { Is } from '~/common/util/pwaUtils';
78
import { useLLM } from '~/common/stores/llms/llms.hooks';
89
import { useModelServiceClientSideFetch } from '~/common/stores/llms/hooks/useModelServiceClientSideFetch';
910

@@ -36,9 +37,11 @@ export function BlockPartError_RequestExceeded(props: {
3637
Request Too Large
3738
</Box>
3839
<div>
39-
Your message or attachments exceed the limit
40-
of the Vercel edge network
41-
{/* Note: Assumption here - since explaing to any 413, it could be any network */}
40+
{/* The 413 can come from any layer in front of the function: the hosted edge network, or a self-hosted
41+
reverse proxy (nginx, etc.). Don't claim "Vercel" unless this is actually the hosted build. */}
42+
{Is.Deployment.VercelFromFrontend
43+
? <>Your message or attachments exceed the ~4.5&nbsp;MB request limit of the Vercel edge network</>
44+
: <>Your message or attachments exceed the request size limit of the server</>}
4245
</div>
4346

4447
{/* Recovery options */}
@@ -100,6 +103,9 @@ export function BlockPartError_RequestExceeded(props: {
100103
<li>Use the cleanup button in the right pane to hide old messages</li>
101104
<li>Remove large attachments from the conversation</li>
102105
{/*<li>Reduce conversation length before sending</li>*/}
106+
{!Is.Deployment.VercelFromFrontend && (
107+
<li>If self-hosting, raise the request size limit on your server or proxy</li>
108+
)}
103109
</Box>
104110
</Box>
105111
)}

src/common/util/pwaUtils.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,12 @@ export const Is = {
3030
Deployment: {
3131
Localhost: clientHostName().includes('localhost:300'),
3232
VercelFromBackendOrSSR: !!process.env.VERCEL_ENV,
33-
VercelFromFrontend: !!process.env.NEXT_PUBLIC_VERCEL_URL,
33+
// NOTE: Vercel auto-exposes NEXT_PUBLIC_VERCEL_URL on hosted prod/preview builds (framework env vars), so keying off
34+
// it would also work - but we use our own NEXT_PUBLIC_DEPLOYMENT_TYPE (set in next.config.ts from VERCEL_ENV): it's
35+
// explicit, self-controlled, and already the canonical deploy signal (see app.release buildInfo). Resolves to
36+
// 'vercel-<env>' on the hosted build, 'local'/custom on self-host. Used to avoid showing Vercel-specific copy (e.g.
37+
// the 413 "edge network" limit) on self-hosted deployments sitting behind nginx/other reverse proxies.
38+
VercelFromFrontend: (process.env.NEXT_PUBLIC_DEPLOYMENT_TYPE ?? '').startsWith('vercel'),
3439
},
3540
} as const;
3641

src/common/util/trpc.client.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,12 @@ const enableLoggerLink = (opts: any) => {
3333
* Detects transport-layer failures by HTTP status / content-type, BEFORE tRPC's JSONL parser turns them into
3434
* engine-specific `SyntaxError`s (which are only string-matchable on V8 - see aix.client.errors.ts). We tag a typed,
3535
* engine-independent marker (`error.cause.aixTransportCode`), read by [Error Channel 1] aixClassifyStreamingError - see the channel map in aix.client.errors.ts.
36-
* - 413 (Vercel rejects request bodies over the edge ~4.5MB limit, as `text/plain`, before the function runs)
36+
* - 413 from whatever sits in front of the function: the hosted Vercel edge (~4.5MB, as `text/plain`), OR a
37+
* self-hosted reverse proxy (nginx `client_max_body_size`, etc.). The classifier emits host-appropriate copy.
3738
* - text/html where a JSON(L) stream is expected (captive portals / proxies / gateway error pages)
3839
*
3940
* NOTE: only the server-side tRPC path passes through here. CSF (client-side-fetch, direct browser->provider) has its
40-
* own error surface and structurally cannot hit a Vercel 413 (there is no edge hop), so it intentionally bypasses this.
41+
* own error surface and structurally cannot hit a front-door 413 (there is no edge/proxy hop), so it bypasses this.
4142
*/
4243
const streamingTransportFetch: typeof fetch = async (input, init) => {
4344
const res = await fetch(input, init);

src/modules/aix/client/aix.client.errors.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,11 @@ import { presentErrorToHumans } from '~/common/util/errorUtils';
1414
// configuration
1515
const AIX_CLIENT_DEV_ASSERTS = process.env.NODE_ENV === 'development';
1616

17-
// user-facing messages reused by the typed transport-marker branch and the legacy string-match fallbacks
18-
const MSG_REQUEST_EXCEEDED = '**Request too large**: Your message or attachments exceed the 4.5MB limit of the Vercel edge network. Tip: use the cleanup button in the right pane to hide messages, remove large attachments or reduce conversation length.';
17+
// user-facing messages reused by the typed transport-marker branch and the legacy string-match fallbacks.
18+
// NOTE: this is the PORTABLE stored text (becomes the error fragment's `part.error` - used for plain rendering, edits,
19+
// exports, logs), so keep it host-neutral. The 413 case is additionally upgraded to the BlockPartError_RequestExceeded
20+
// component, which OVERRIDES this string in chat and owns the host-aware phrasing (Vercel 4.5MB vs generic self-host).
21+
const MSG_REQUEST_EXCEEDED = '**Request too large**: Your message or attachments exceed the request size limit of the server. Tip: use the cleanup button in the right pane to hide messages, remove large attachments or reduce conversation length.';
1922
const MSG_RESPONSE_CAPTIVE = '**Network issue**: The network returned an HTML page instead of expected data. This can be a Wi-Fi sign-in page, a proxy or browser extension, or a temporary gateway error. Please **refresh and try again**, or check your connection and disable blockers. Additional details may be available in the browser console.';
2023

2124

@@ -90,9 +93,9 @@ export function aixClassifyStreamingError(error: any, isUserAbort: boolean, hasF
9093
// Initial connection failures, HTTP errors, or text responses that blow up tRPC's JSON parser
9194
if (error instanceof TRPCClientError) {
9295

93-
// Server-side PAYLOAD_TOO_LARGE - HTTP 413
96+
// Server-side PAYLOAD_TOO_LARGE - HTTP 413 (fallback; streamingTransportFetch normally tags this earlier)
9497
if (error.data?.httpStatus === 413)
95-
return { errorType: 'request-exceeded', errorMessage: '**Request too large**: This request exceed the size limit of the servers' };
98+
return { errorType: 'request-exceeded', errorMessage: MSG_REQUEST_EXCEEDED };
9699

97100
switch (error.cause?.message) {
98101
/**

0 commit comments

Comments
 (0)