linshenkx/prompt-optimizer · warning · Error

Example image request failed: ${resp.status}

Error message

Example image request failed: ${resp.status}

What it means

fetchImageAsBase64 GETs an example image referenced by an imported Garden prompt. If the HTTP response status is not ok (outside 200-299), it throws with the embedded status code. This is a plain network/HTTP failure on a secondary asset, distinct from the prompt JSON fetch.

Source

Thrown at packages/ui/src/composables/app/useAppPromptGardenImport.ts:733

const resolveGardenUrl = (opts: { gardenBaseUrl: string | null; url: string }): string | null => {
  const raw = String(opts.url || '').trim()
  if (!raw) return null
  if (/^https?:\/\//u.test(raw)) return raw

  const base = opts.gardenBaseUrl ? normalizeBaseUrl(opts.gardenBaseUrl) : null
  if (!base) return null

  try {
    return new URL(raw, `${base}/`).toString()
  } catch {
    return null
  }
}

const fetchImageAsBase64 = async (absoluteUrl: string): Promise<{ b64: string; mimeType: string } | null> => {
  const resp = await fetch(absoluteUrl, { method: 'GET' })
  if (!resp.ok) {
    throw new Error(`Example image request failed: ${resp.status}`)
  }

  const headerType = resp.headers.get('content-type')
  const mimeType = typeof headerType === 'string' ? headerType.split(';')[0].trim() : ''

  type BufferLike = {
    from: (data: ArrayBuffer) => { toString: (encoding: 'base64') => string }
  }

  const maybeBuffer = (globalThis as unknown as { Buffer?: BufferLike }).Buffer
  if (maybeBuffer && typeof maybeBuffer.from === 'function') {
    const ab = await resp.arrayBuffer()
    const b64 = maybeBuffer.from(ab).toString('base64')
    return { b64, mimeType: mimeType || 'application/octet-stream' }
  }

  if (typeof FileReader === 'undefined') {
    throw new Error('FileReader is not available to decode images')

View on GitHub (pinned to 3e677b1d9f)

Solutions

  1. Retry the fetch manually with the exact absoluteUrl to read the status code (404 vs 403 vs 5xx)
  2. If 403 with signed URLs, re-import the prompt soon after export so URLs are fresh, or fix the signing/allowlist
  3. If 404, drop the dead image reference from the prompt or update it to a stable URL
  4. Wrap the import flow so a single failed example image degrades gracefully instead of aborting the whole import

Example fix

// before
const { b64, mimeType } = await fetchImageAsBase64(absoluteUrl)

// after
let image: { b64: string; mimeType: string } | null = null
try {
  image = await fetchImageAsBase64(absoluteUrl)
} catch (err) {
  console.warn(`Skipping example image (${absoluteUrl}):`, err)
}
Defensive patterns

Strategy: fallback

Validate before calling

const probe = await fetch(absoluteUrl, { method: 'HEAD' })
if (!probe.ok) skipImage(`Image unavailable (HTTP ${probe.status})`)

Try / catch

try { image = await fetchImageAsBase64(url) } catch (e) { console.warn('Skipping example image:', e); image = null }

Prevention

When it happens

Trigger: Any non-2xx status: 404 (image URL stale or deleted), 403 (hotlink protection / expired signed URL), 401 (auth required), 5xx (origin server error), or a CORS-blocked request surfacing as a failure status via the proxy.

Common situations: Garden prompts referencing images with expiring signed URLs (S3 presigned links past expiry); CDN hotlink protection; relative image URLs resolved against the wrong base; image deleted upstream after prompt publication.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


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