Skip to content

ui: don't trust a partial dist dir (fixes 'missing loading.html' build abort on Termux/sharp failure)#225

Merged
TheTom merged 1 commit into
feature/turboquant-kv-cachefrom
fix-ui-assets-partial-dist
Jul 18, 2026
Merged

ui: don't trust a partial dist dir (fixes 'missing loading.html' build abort on Termux/sharp failure)#225
TheTom merged 1 commit into
feature/turboquant-kv-cachefrom
fix-ui-assets-partial-dist

Conversation

@TheTom

@TheTom TheTom commented Jul 18, 2026

Copy link
Copy Markdown
Owner

Problem

scripts/ui-assets.cmake trusted a UI dist directory on the presence of index.html alone. When an npm PWA-assets build dies partway through, it can leave a dist with index.html but missing loading.html, the PWA manifest, the service worker, etc. The script then hands that partial dir to llama-ui-embed, which aborts the entire build:

missing required asset(s):
    loading.html
    manifest.webmanifest
    ...

This has now hit two users. The common trigger is the native sharp dependency (via @vite-pwa/assets-generator) failing on Termux / very new Node.js:

sharp/lib/utility.js:27  TypeError: Cannot read properties of undefined (reading 'output')

npm exits non-zero, but a partial tools/ui/dist/ (or a stale one) is left behind and gets picked up as if it were a valid pre-built UI.

Fix

Add dist_is_complete(): a dist is only usable if it holds the complete asset set llama-ui-embed requires (index.html, loading.html, manifest.webmanifest, sw.js, build.json, version.json, bundle*.{js,css}, workbox*.js), matched by basename recursively to mirror embed.cpp's own check. Gate all three trust points on it:

  • pre-built tools/ui/dist: skip a partial dir, fall through to npm/HF
  • HF stamp-skip: only skip the download when the cached dist is actually complete
  • final fallback: if provisioning failed and the dist is partial, drop it and build a no-embedded-UI binary with a clear message, instead of aborting the whole build

Net effect: a broken/partial UI build (sharp failure, interrupted download) now falls through to the HF-downloaded prebuilt UI, or degrades to a no-UI binary — it no longer hard-fails the whole llama.cpp build.

Testing

dist_is_complete verified via cmake -P against four fixtures:

fixture expected result
partial (index.html + a bundle only) rejected ✅ FALSE
complete (full asset set) accepted ✅ TRUE
empty rejected ✅ FALSE
nested (real vite assets/ subdir layout) accepted ✅ TRUE

For affected users right now

Cleanest workaround without this patch: configure with -DBUILD_UI=OFF so the npm/sharp path never runs and the HF-downloaded prebuilt UI is used. rm -rf build also recovers, since a clean build has no partial dist to trip over and the HF fallback provisions a complete one.

…bedding

A UI dist directory was trusted on the presence of index.html alone. When an
npm PWA-assets build dies partway -- e.g. the native `sharp` step failing on
Termux / very new Node.js, which is common -- it can leave a dist with
index.html but without loading.html, the PWA manifest, service worker, etc.
ui-assets.cmake would then hand that partial dir to llama-ui-embed, which
aborts the entire build with 'missing required asset(s): loading.html ...'.

Add dist_is_complete(): a dist is only usable if it holds the complete asset
set llama-ui-embed requires (index.html, loading.html, manifest.webmanifest,
sw.js, build.json, version.json, bundle*.{js,css}, workbox*.js), matched by
basename recursively to mirror embed.cpp's own check. Gate all three trust
points on it:
  - pre-built tools/ui/dist: skip a partial dir, fall through to npm/HF
  - HF stamp-skip: only skip the fetch when the cached dist is complete
  - final fallback: if provisioning failed and the dist is partial, drop it
    and build a no-embedded-UI binary with a clear message instead of aborting

Net effect: a broken/partial UI build (sharp failure, interrupted download)
falls through to the HF-downloaded prebuilt UI, or degrades to a no-UI binary,
instead of hard-failing the whole llama.cpp build. Reported by two users hitting
the 'missing loading.html' abort on Termux.

dist_is_complete verified via cmake -P against partial/complete/empty/nested
fixtures (nested = real vite assets/ subdir layout).
@TheTom
TheTom merged commit c26cbdf into feature/turboquant-kv-cache Jul 18, 2026
7 of 21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant