Closed bug report

Widget script loading rejects query URLs and raw companion ES modules

John Lauer · 1mo ago ·closed by Colby Knox

Environment: adom-wiki CLI 1.7.39, component-widgets 1.1.9, Pup 2.0.457, Adom Bridge 2.1.96, Windows; observed 10 September 2026. Wiki server version was not exposed in the responses inspected.

While deploying an optional LOD viewer, two script-loading assumptions failed in the live registered widget frame:

  1. A registry script URL of https://wiki.adom.inc/adom/component-widgets/render/widgets/chip-thumbnail-widget.js?v=1.1.9 made /widget-script/adom-component-lod.js return HTTP 404. Its JSON error was: "Widget script file not found in its page repo". The same repo file existed and returned 200. Removing the query suffix restored the registered script endpoint. The suffix appears to be treated as part of the repo filename; this is an inference from the before/after result.
  2. A companion ES module at /adom/component-widgets/render/widgets/component-lod-preview.js returns 200 with Content-Type application/octet-stream and X-Content-Type-Options nosniff. It cannot be imported as JavaScript from that raw file endpoint. The file API route has the same content type.

Expected: either support query-bearing registry URLs and correctly typed companion JS modules, or reject unsupported forms at registry/page publication with an actionable AI hint naming the supported route. This prevents a successful registry push from silently producing a blank widget.

Recovery: restored query-free registry paths immediately. The next widget revision bundles the small control runtime and lazily imports only the canonical viewer through the existing /static/vendor/ JavaScript route. No authentication or CSP restrictions were weakened. The attached HTTP checks show the restored script endpoint and the companion-module MIME behavior. These are HTTP/loading failures; no private component page content is attached.

wiki-lod-script-http-evidence.json

2 Replies

Colby Knox · 1mo ago

Both confirmed and fixed, John. Your inference on (1) was right: the registry parser kept everything after /render/ as the repo path, so ?v=1.1.9 became part of the filename and the read at HEAD failed. On (2) the download posture is deliberate (user JS never becomes a wiki-origin executable, so a sanitizer bypass has no CSP-proof payload to point at), which is why /widget-script/ exists as the registry-gated JS route; it only knew the one registered file.

What ships:

  • A registry script URL may carry ?v=... or a fragment; both are stripped before the repo read. Your original chip-thumbnail-widget.js?v=1.1.9 form now serves.
  • Companion modules: /widget-script/<name>/<path relative to the registered script> serves any .js or .mjs next to or below the registered script in its page repo, as text/javascript with nosniff, gated by the same registry entry. Nothing above the script's directory, no .., non-JS refused (WIDGET_COMPANION_INVALID). For your case: import("/widget-script/adom-component-lod/component-lod-preview.js"). Use the absolute path: a classic <script> resolves a relative import() against the frame document, not the script.
  • The /widget-script/ 404 now says which page and repo path it looked for (WIDGET_SCRIPT_UNRESOLVED, data.{owner,slug,path}).
  • Push-time hints, so a blank widget never ships silently: a widgets.json push to the registry page lists every entry whose wiki-hosted script is not in its repo (WIDGET_SCRIPT_UNRESOLVED, warning) and every entry the sanitizer dropped (WIDGET_REGISTRY_ENTRIES_DROPPED); a JS file pushed next to a registered script is told the route it loads from (WIDGET_COMPANION_ROUTE, info).

/render/ and the file API keep serving JS as a download; that is not changing. Prod has it (tag 680f9d4, 17:13 UTC): /widget-script/adom-component-lod/component-lod-preview.js answers 200 text/javascript there right now. The LOD entry currently points at the thumbnail widget, so once you point it back at the real script the companion route is ready for it.

Colby Knox · 28d ago

Closing as shipped: both fixes have been on prod since 2026-09-10 (git-wiki 680f9d4): registry script URLs keep their query string out of the repo path, and the widget-script route serves raw companion ES modules through the registry gate. Reopen if either surfaces again with the CLI and component-widgets versions.

Log in to reply.