Appearance
Route diagnostics
When a URL doesn't work, the bug is almost always in one of three places:
- The gateway can't see the runtime that should serve the URL.
- The runtime is registered but the asset endpoint is misconfigured.
- The actual file path doesn't exist or path-traversal-rejects.
This page is the diagnostic flow for each.
Step 1: Is the URL reaching the gateway?
bash
curl -fsS http://127.0.0.1:3100/healthzIf /healthz works but /apps/foo/ doesn't, the gateway is alive and the issue is downstream. If /healthz itself fails, see Health.
Step 2: What does gateway.http.status say?
bash
matrix invoke system.gateway.http gateway.http.status '{}'Returns the current set of webapp routes:
json
{
"ok": true,
"mount": "system.gateway.http",
"routeCount": 5,
"routes": [
{
"appName": "chat",
"runtimeId": "RUNTIME-HOST-CHAT",
"packageName": "@open-matrix/chat",
"assetMount": "chat.http",
"routePrefix": "/apps/chat/",
"displayName": "Chat",
"shells": ["platform"],
"source": "host-runtime-record"
},
...
]
}Diagnostic question: Is the appName you expect listed?
- Not listed. The gateway can't see this runtime. Either the runtime isn't running, or its
metadata.webappblock is missing/malformed. Go to step 3. - Listed but wrong. Check
assetMountandruntimeId. A misconfigured webapp record can have the right appName but point at the wrong asset endpoint.
Step 3: Is the runtime actually running?
bash
matrix invoke system.runtimes runtimes.registered '{}'
# or
hivecast runtimesLook for the runtime that should own the appName. Each runtime has a status field. If status is stopped, failed, or starting, the gateway will exclude it from _loadRoutes.
json
{
"runtimes": [
{
"runtimeId": "RUNTIME-HOST-CHAT",
"type": "@open-matrix/chat",
"status": "running", // ← must be "running"
"metadata": {
"webapp": {
"appName": "chat",
"assetMount": "chat.http",
"routePrefix": "/apps/chat/"
}
}
}
]
}If status is wrong, fix it: matrix start <runtime-id> or check the runtime's logs for why it failed to start.
Step 4: Does gateway.http.resolve find it?
bash
matrix invoke system.gateway.http gateway.http.resolve '{"pathname":"/apps/foo/index.html"}'If the route exists this returns:
json
{
"ok": true,
"pathname": "/apps/foo/index.html",
"resolution": {
"routeKind": "matrix-asset-endpoint",
"appName": "foo",
"assetPath": "index.html",
"runtimeId": "RUNTIME-HOST-FOO",
"assetMount": "foo.http",
"source": "host-runtime-record"
}
}If resolution: null, the gateway can't match the URL. Common causes:
- The
appNamein the URL doesn't match any registered webapp. - The runtime is registered but its status is not
running.
Step 5: Does the asset endpoint resolve the path?
bash
matrix invoke chat.http http.asset.resolve '{"pathname":"/apps/chat/assets/index.js"}'Returns:
json
{
"ok": true,
"packageName": "@open-matrix/chat",
"appName": "chat",
"pathname": "/apps/chat/assets/index.js",
"assetPath": "assets/index.js",
"filePath": "/.../node_modules/@open-matrix/chat/dist/browser/assets/index.js"
}If ok: false, the asset doesn't exist on disk. Possible causes:
- The package wasn't built (
dist/browser/empty). - The package's
webapp.distDiris misconfigured. - The asset endpoint's
assetEndpointprops (set at mount time) point at the wrong directory.
Step 6: Does the actual fetch work?
bash
matrix invoke chat.http http.asset.request '{"pathname":"/apps/chat/index.html","method":"GET"}'This goes through the full path-traversal check, file read, MIME-type lookup, and base64 encoding. If this works but the HTTP request doesn't, the issue is in the gateway's relay layer or the listener's response writing — check gateway logs.
Common diagnoses
| Symptom | Step where it surfaces | Likely cause |
|---|---|---|
/apps/foo/ returns 404 | Step 4 | No route registered for foo |
/apps/foo/ returns the platform shell | Step 4 | foo parsed as something else first; check public-namespace pattern |
| Right runtime, wrong file served | Step 5 | distDir resolved to wrong path |
| Asset returns but 502 with "exceeded relay limit" | Step 6 | File >10 MB |
| 200 OK but wrong content-type | Step 6 | File extension not in MIME_TYPES; gateway returns octet-stream |
See also
Source:
projects/matrix-3/packages/system-gateway-http/src/index.ts:262-383.