# Public asset references exist on disk

- **Pattern:** `ab-000041` (`ai-slop-hallucinations.asset-references.public-assets-exist`)
- **Severity:** medium
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000041
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000041)

## Why it matters

A missing file under `public/` — a hero image, a logo, a web font — renders as a broken image icon, a ghosted logo slot, or a fallback system font in production. None of these fail the build; they degrade the first paint silently. AI tools frequently reference `/images/hero.png` or `/fonts/Inter.woff2` that were never committed to `public/`, and the failure only surfaces when a designer or customer notices the missing asset days later.

## Severity rationale

Medium because missing public assets ship silently and degrade the visual polish of every page that references them.

## Remediation

For each unresolved reference, either drop the file into `public/` at the expected path or correct the reference to an asset that exists. On a Next.js project the `<Image>` component from `next/image` surfaces missing-file errors at build time under `output: 'export'`:

```tsx
import Image from 'next/image'
<Image src="/images/hero.png" alt="Hero" width={1200} height={630} />
```

Confirm the file exists at `public/images/hero.png`.

## Detection

- **ID:** `public-assets-exist`
- **Severity:** `medium`
- **What to look for:** Walk all `.tsx`/`.jsx`/`.html`/`.svelte`/`.vue`/`.astro`/`.css` files for references to public assets via these patterns: `<img src="/...">`, `<source srcSet="/...">`, `<link href="/...">`, `<video src="/...">`, `<audio src="/...">`, `<picture><source srcSet="/...">`, `url(/...)` in CSS, `import("/...")`, `new URL("/...", ...)`, and bare string literals starting with `/` passed to image-related props (`src`, `poster`, `image`, `cover`, `thumbnail`, `icon`, `logo`). For each path, check whether the file exists under `public/` (Next.js, Remix, Astro), `static/` (Nuxt, SvelteKit), or `app/` for Next.js root-level icons. Count all public asset references, total resolved on disk, total unresolved.
- **Pass criteria:** 100% of public asset references resolve to actual files. Report: "X public asset references inspected, Y resolved, 0 unresolved."
- **Fail criteria:** At least 1 public asset reference does not resolve to a file under `public/`/`static/`.
- **Skip (N/A) when:** No `public/` and no `static/` directory exists at the project root.
- **Detail on fail:** `"3 missing public assets: '/images/hero.png' in src/app/page.tsx (no public/images/hero.png), '/og-image.jpg' in src/app/layout.tsx (no public/og-image.jpg), '/fonts/Inter.woff2' in src/styles/globals.css"`
- **Remediation:** A missing public asset shows a broken image, missing logo, or 404'd font in production. Fix each one by either creating the file or updating the reference:

  ```bash
  # Find missing assets
  ls public/

  # Add the file
  cp ~/Downloads/hero.png public/images/hero.png
  ```

  For Next.js, prefer `<Image src="/path" />` from `next/image` over raw `<img>` so the build catches missing assets at build time when `output: 'export'` is used.

Taxons: reference-integrity

HTML version: https://auditbuffet.com/patterns/ab-000041
