linshenkx/prompt-optimizer · warning · Error

Image storage quota exceeded: projected size ${nextTotalByte

Error message

Image storage quota exceeded: projected size ${nextTotalBytes} exceeds maxCacheSize ${config.maxCacheSize}

What it means

The sibling size check in assertStorageQuotaForPayload: it projects total cached bytes after adding the new payload and throws when the sum would exceed config.maxCacheSize. Large images (or many small ones) can blow a byte-level budget even when the count is fine.

Source

Thrown at packages/ui/src/utils/image-asset-storage.ts:202

  const nextCount = stats.count + 1
  const nextTotalBytes = stats.totalBytes + Math.floor(payload.b64.length * 0.75)

  if (
    typeof config.maxCount === 'number' &&
    Number.isFinite(config.maxCount) &&
    nextCount > config.maxCount
  ) {
    throw new Error(
      `Image storage quota exceeded: projected count ${nextCount} exceeds maxCount ${config.maxCount}`,
    )
  }

  if (
    typeof config.maxCacheSize === 'number' &&
    Number.isFinite(config.maxCacheSize) &&
    nextTotalBytes > config.maxCacheSize
  ) {
    throw new Error(
      `Image storage quota exceeded: projected size ${nextTotalBytes} exceeds maxCacheSize ${config.maxCacheSize}`,
    )
  }
}

export const persistImagePayloadAsAssetId = async (
  opts: PersistImagePayloadOptions,
): Promise<string | null> => {
  const { payload, storageService, sourceType = 'uploaded', metadata } = opts
  if (!storageService || !payload?.b64) return null

  const imageId = await computeStableImageId(payload.b64, payload.mimeType)
  await assertStorageQuotaForPayload(storageService, imageId, payload)
  const existing = await storageService.getMetadata(imageId)
  if (!existing) {
    await storageService.saveImage({
      metadata: {
        id: imageId,

View on GitHub (pinned to 3e677b1d9f)

Solutions

  1. Downscale/compress images before persisting (canvas resize, quality reduction)
  2. Evict oldest assets by size until the projected total fits under maxCacheSize
  3. Raise maxCacheSize or store large assets out-of-cache (blob URLs / server-side)
  4. Check projected size before insert and surface a quota UI to the user

Example fix

// before
await persistImagePayloadAsAssetId(payload) // 4MB image, 5MB cache mostly full -> throws

// after
const compressed = await downscaleToMaxBytes(payload, 512 * 1024)
while (projectedTotalBytes(compressed) > config.maxCacheSize) {
  await deleteOldestImageAsset()
}
await persistImagePayloadAsAssetId(compressed)
Defensive patterns

Strategy: validation

Validate before calling

const projected = currentTotalBytes() + payload.b64.length
if (projected > config.maxCacheSize) {
  await evictOldestUntilFits(payload.b64.length)
  // or: payload = await downscaleToMaxBytes(payload, budget)
}

Type guard

null

Try / catch

try { await persistImagePayloadAsAssetId(payload) } catch (e) { if (e.message.startsWith('Image storage quota exceeded: projected size')) { payload = await downscaleToMaxBytes(payload, 512 * 1024); return persistImagePayloadAsAssetId(payload) } throw e }

Prevention

When it happens

Trigger: Persisting an image whose byte length pushes nextTotalBytes over maxCacheSize — e.g. a multi-MB photo into a 5MB cache; several large uploads accumulating to the cap; base64 size accounting overshooting due to a lowered config.

Common situations: High-resolution uploads without downscaling; config.maxCacheSize set in MB but code comparing bytes or vice versa; users pasting screenshots repeatedly; IndexedDB-backed caches nearing device limits.

Related errors


AI-assisted analysis of linshenkx/prompt-optimizer@3e677b1d9f (2026-08-27). Data as JSON: /api/errors/3979347dfde53882. Report an issue: GitHub.