···176176 setSkippedFiles(result.skippedFiles || [])
177177 setFailedFiles(result.failedFiles || [])
178178 setUploadedCount(result.uploadedCount || result.fileCount || 0)
179179+180180+ // Debug: log failed files
181181+ console.log('Failed files:', result.failedFiles)
182182+183183+ // Check for 419/413 errors and show alert
184184+ const hasSizeError = result.failedFiles?.some((file: any) => {
185185+ const error = file.error?.toLowerCase() || ''
186186+ console.log('Checking error:', error, 'contains PDS?', error.includes('pds'))
187187+ return error.includes('pds is not allowing') ||
188188+ error.includes('your pds is not allowing') ||
189189+ error.includes('request entity too large')
190190+ })
191191+192192+ console.log('Has size error:', hasSizeError)
193193+194194+ if (hasSizeError) {
195195+ window.alert('Some files were too large for your PDS. Your PDS is not allowing uploads large enough to store your site. Please contact your PDS host. This could also possibly be a result of it being behind Cloudflare free tier.')
196196+ }
197197+179198 setSelectedSiteRkey('')
180199 setNewSiteName('')
181200 setSelectedFiles(null)
···350350351351 const isTimeout = error?.name === 'AbortError' || error?.message === 'Upload timeout';
352352 const isRateLimited = error?.status === 429 || error?.message?.toLowerCase().includes('rate');
353353+ const isRequestEntityTooLarge = error?.status === 419 || error?.status === 413;
354354+355355+ // Special handling for 419/413 Request Entity Too Large errors
356356+ if (isRequestEntityTooLarge) {
357357+ const customError = new Error('Your PDS is not allowing uploads large enough to store your site. Please contact your PDS host. This could also possibly be a result of it being behind Cloudflare free tier.');
358358+ (customError as any).status = 419;
359359+ throw customError;
360360+ }
353361354362 // Retry on DPoP nonce conflicts, timeouts, or rate limits
355363 if ((isDPoPNonceError || isTimeout || isRateLimited) && attempt < maxRetries - 1) {