Skip to content

fix: load models on GitHub Pages sub-path deployments (issue #13)#14

Merged
konard merged 5 commits into
mainfrom
issue-13-65bf0a6ae9fc
Jun 10, 2026
Merged

fix: load models on GitHub Pages sub-path deployments (issue #13)#14
konard merged 5 commits into
mainfrom
issue-13-65bf0a6ae9fc

Conversation

@konard

@konard konard commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Fix sub-path (GitHub Pages project-site) model loading — issue #13

Fixes #13.

The bug

On the deployed site https://link-assistant.github.io/model-in-browser/ (a
GitHub Pages project site, served under the /model-in-browser/ sub-path)
the app failed with:

Error: no available backend found. ERR: [wasm] importing a module script failed

No model ever loaded; Retry Load reproduced the failure every time.

Root cause

The inference worker derived ONNX Runtime Web's WASM wasmPaths from
self.location.origin, which is scheme + host + port only — it drops the
/model-in-browser/ sub-path. ORT then tried to import() its glue module
ort-wasm-simd-threaded.jsep.mjs from https://host/ort/… instead of
https://host/model-in-browser/ort/…, which 404s. The failed dynamic import
surfaces inside ORT as the generic "no available backend found" message.

It shipped unnoticed because the e2e suite ran against vite preview, which
serves at the origin root — where origin-based resolution is accidentally
correct, so the sub-path layout that triggers the bug was never exercised.

The fix

Resolve the ORT base from the deployment base, not the origin, in both
threads (defence in depth):

  • App.tsx uses import.meta.env.BASE_URL (Vite's configured base, sub-path-aware)
    and posts it to the worker.
  • worker.ts prefers that value; its fallback resolves ../ort/ relative to
    the worker's own location (<base>assets/…<base>ort/), so it is correct
    under any sub-path with no origin involved.

Codebase-wide audit (R6)

The ORT wasmPaths derivation was the only origin-rooted asset path. The
Candle WASM engine, app JS/CSS bundles, and model weights are all resolved
relatively (Vite, base: './') or fetched from absolute remote URLs, so they are
already sub-path-safe. Full audit table in the case study.

Debug / verbose mode (R4)

Added ?debug=1 (or localStorage.mib_debug = '1'): the app and worker now log
the resolved ORT base path, so any future asset-path problem is self-diagnosing.

Tests (R1, R2)

  • browser-commander e2eweb/e2e/browser-commander/subpath-load.mjs
    (npm run test:e2e:bc): boots a sub-path server, drives Chromium via
    browser-commander,
    loads SmolLM2 135M Instruct (q8), and asserts the ORT glue is served from
    the sub-path with no backend error. Passing.
  • Playwright sub-path specweb/e2e/subpath.spec.ts run by a new
    chromium-subpath project against web/e2e/subpath-server.mjs (reproduces the
    GitHub Pages project-site layout with production COOP/COEP headers). Fails on
    the pre-fix code, passes on the fix.
    Passing (9.9s).
  • Manual Playwright verification: model loads and generates text end-to-end under
    the sub-path.

Case study (R3)

docs/case-studies/issue-13/README.md — timeline, full requirements table
(R1–R7), root-cause analysis, the fix, codebase-wide audit, the
report-upstream decision (R5: N/A, bug is in this repo), online research with
citations, and before/after screenshots.

Upstream report (R5)

Not applicable — the root cause is in this repository's code. ORT/transformers.js
behaved correctly (they requested the configured URL); the supported
env.backends.onnx.wasm.wasmPaths override is exactly what the fix uses.

Screenshots

Reported failure After fix — ready After fix — generation
original ready generation

Release

Adds a patch changelog fragment (changelog.d/20260610_150000_fix_subpath_ort_backend.md).

Adding .gitkeep for PR creation (default mode).
This file will be removed when the task is complete.

Issue: #13
@konard konard self-assigned this Jun 10, 2026
@konard

konard commented Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

⏳ Usage Limit Reached

The automated solution draft was interrupted because the Anthropic Claude Code usage limit was reached.

📊 Limit Information

  • Tool: Anthropic Claude Code
  • Limit Type: Usage limit exceeded
  • Reset Time: in 2h 7m (Jun 10, 4:50 PM UTC)
  • Session ID: 27a57714-f399-41b0-b055-a5ed9517b38f

🔄 How to Continue

Auto-resume is enabled. The session will automatically resume (with context preserved) when the limit resets.

🤖 Models used:

  • Tool: Anthropic Claude Code
  • Requested: opus
  • Model: Claude Opus 4.8 (claude-opus-4-8)

📎 Execution log uploaded as Gist (3462KB)


This session was interrupted due to usage limits. The session will automatically resume when the limit resets.

@konard

konard commented Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

Auto Resume (on limit reset)

Auto-resuming automated work session at 2026-06-10T17:01:03.574Z

This session automatically resumed after the usage limit reset, continuing with the previous context preserved.

The PR has been converted to draft mode while work is in progress.

This is an auto-resumed session. Please wait for the session to finish, and provide your feedback.

- Add browser-commander e2e (web/e2e/browser-commander/subpath-load.mjs,
  npm run test:e2e:bc) loading SmolLM2 135M Instruct under the /<repo>/
  sub-path, asserting the ORT glue is served from the sub-path and no
  'no available backend found' error appears (R1).
- Add the Playwright chromium-subpath project + spec and the sub-path
  static server that reproduce the GitHub Pages project-site layout.
- Add docs/case-studies/issue-13: timeline, requirements (R1-R7),
  root-cause analysis, the fix, codebase-wide audit, online research
  with citations, and before/after screenshots (R3).
- Add changelog fragment for the sub-path ORT backend fix.
- Relocate stray repro screenshots into the case-study folder.
@konard konard changed the title [WIP] It does not work fix: load models on GitHub Pages sub-path deployments (issue #13) Jun 10, 2026
@konard konard marked this pull request as ready for review June 10, 2026 17:12
Wires the issue-#13 browser-commander e2e (npm run test:e2e:bc) into the
E2E workflow so the sub-path model-load regression is verified continuously,
not only manually.
@konard

konard commented Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

Working session summary

All requirements are addressed and PR #14 is finalized. Summary of what was completed:

Issue #13 — "It does not work" — Resolved

Root cause: On the GitHub Pages project-site deployment (https://link-assistant.github.io/model-in-browser/), the inference worker derived ONNX Runtime Web's WASM wasmPaths from self.location.origin — which is host-only and drops the /model-in-browser/ sub-path. ORT then 404'd on its glue module ort-wasm-simd-threaded.jsep.mjs (requested from /ort/… instead of /model-in-browser/ort/…), surfacing as the generic "no available backend found … importing a module script failed". It shipped unnoticed because the e2e suite ran against vite preview at the origin root, where origin-based resolution is accidentally correct.

The fix: Resolve the ORT base from the deployment base in both threads — App.tsx uses import.meta.env.BASE_URL; worker.ts falls back to a worker-relative ../ort/. Neither involves origin, so it's correct under any sub-path.

Requirements delivered:

  • R1 — browser-commander e2e test (npm run test:e2e:bc) loading SmolLM2 135M Instruct under the sub-path — passing locally and in CI.
  • R2 — Playwright sub-path regression spec + manual verification; root cause fixed.
  • R3docs/case-studies/issue-13/README.md: timeline, requirements table, root-cause analysis, codebase audit, online research with citations, before/after screenshots.
  • R4?debug=1 / localStorage.mib_debug verbose mode logging the resolved ORT path.
  • R5 — N/A (bug is in this repo's code; documented why).
  • R6 — Audited all asset paths; ORT wasmPaths was the only origin-rooted one.
  • R7 — All in PR fix: load models on GitHub Pages sub-path deployments (issue #13) #14.

Verification: All three CI workflows pass (CI/CD Pipeline, Build and Deploy, E2E Tests including the new browser-commander step). Working tree clean, PR marked ready, changelog fragment added.

PR: #14


This summary was automatically extracted from the AI working session output.

@konard

konard commented Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

🔄 Solution Draft Log (auto resume on limit reset)

This log file contains the complete execution trace of the AI solution draft process.

💰 Cost estimation:

  • Public pricing estimate: $10.088122
  • Calculated by Anthropic: $4.607969
  • Difference: $-5.480153 (-54.32%)

📊 Context and tokens usage:

Claude Opus 4.8: (3 sub-sessions)

  1. 113.5K / 1M (11%) input tokens, 23.6K / 128K (18%) output tokens
  2. 114.1K / 1M (11%) input tokens, 32.2K / 128K (25%) output tokens
  3. 75.4K / 1M (8%) input tokens, 20.9K / 128K (16%) output tokens

Total: (25.0K new + 488.7K cache writes + 9.9M cache reads) input tokens, 76.7K output tokens, $10.060093 cost

Claude Haiku 4.5:

  • 15.4K / 200K (8%) input tokens, 518 / 64K (1%) output tokens

Total: 15.4K input tokens, 518 output tokens, $0.028029 cost

🤖 Models used:

  • Tool: Anthropic Claude Code
  • Requested: opus
  • Main model: Claude Opus 4.8 (claude-opus-4-8)
  • Additional models:
    • Claude Haiku 4.5 (claude-haiku-4-5-20251001)

Note: This session was automatically resumed after a usage limit reset, with the previous context preserved.

📎 Log file uploaded as Gist (1623KB)


Now working session is ended, feel free to review and add any feedback on the solution draft.

@konard

konard commented Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

✅ Ready to merge

This pull request is now ready to be merged:

  • All CI checks have passed
  • No merge conflicts
  • No pending changes

Monitored by hive-mind with --auto-restart-until-mergeable flag

@konard konard merged commit 92986fc into main Jun 10, 2026
11 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.

It does not work

1 participant