moeru-ai/airi · error · Error
Extension asset server base URL is unavailable; start the as
Error message
Extension asset server base URL is unavailable; start the asset server before creating asset sessions
What it means
Thrown inside createAssetSession when readBaseUrl() returns a falsy value, meaning the extension asset HTTP server has no resolvable base URL yet. Asset sessions produce URLs that embed the server's base URL, so creating a session before the server is listening would yield unusable URLs.
Source
Thrown at apps/stage-tamagotchi/src/main/services/airi/plugins/features/static-assets/index.ts:221
await revokeSessions(server.revokeAll())
await server.stop()
},
getBaseUrl() {
return readBaseUrl()
},
async createAssetSession(input) {
const session = server.createSession({
extensionId: input.extensionId,
version: input.version,
ownerSessionId: input.ownerSessionId,
pathPrefix: input.pathPrefix,
ttlMs: input.ttlMs,
})
try {
const baseUrl = readBaseUrl()
if (!baseUrl) {
throw new Error('Extension asset server base URL is unavailable; start the asset server before creating asset sessions')
}
const mountedPath = buildMountedStaticAssetPath({
extensionId: input.extensionId,
assetSessionId: session.assetSessionId,
assetPath: input.routeAssetPath,
})
if (!mountedPath) {
throw new RangeError('Extension asset session routeAssetPath must be a safe extension asset path')
}
const cookie = createExtensionAssetCookie(baseUrl, session)
await options.cookieAdapter.setCookie(cookie)
return {
url: new URL(mountedPath, baseUrl).toString(),
assetSessionId: session.assetSessionId,View on GitHub (pinned to 27111382b4)
Solutions
- Ensure the asset HTTP server is started (and readBaseUrl is populated) before any code path calls createAssetSession.
- Check the asset server startup logs for a bind/listen failure (port conflict, permission denied) and resolve it.
- Defer createAssetSession calls until after the server-ready signal is emitted, or await the server start promise.
- If the server URL must be configured manually, verify the configured base URL setting is non-empty.
Example fix
// before
const session = await createAssetSession({ extensionId, ... })
// after
await ensureAssetServerStarted()
const session = await createAssetSession({ extensionId, ... }) Defensive patterns
Strategy: validation
Validate before calling
// Ensure the asset server base URL is available before creating a session
await ensureAssetServerReady()
const baseUrl = readBaseUrl()
if (!baseUrl) {
throw new Error('Asset server not ready; cannot create session')
}
const session = await createAssetSession(input) Try / catch
try {
return await createAssetSession(input)
} catch (e) {
if (/base URL is unavailable/.test(errorMessageFrom(e) ?? '')) {
await ensureAssetServerReady()
return await createAssetSession(input)
}
throw e
} Prevention
- Order startup so the asset HTTP server starts before features that call createAssetSession.
- Expose a readiness signal/promise from the asset server and await it in dependent features.
- Fail fast in the server start path (log bind errors) so readBaseUrl being empty is diagnosable.
When it happens
Trigger: An extension (or the plugins/features/static-assets module) calls createAssetSession before the underlying asset HTTP server has been started, or while it is still binding its port and readBaseUrl has not yet captured the listening address.
Common situations: Plugin initialization order is wrong — the static-assets feature is invoked before the HTTP server bootstrap completes; the server failed to start (port in use) so readBaseUrl never gets set; a race during app startup where an extension load triggers createAssetSession during the boot window.
Related errors
- EXTENSION_ASSET_METHOD_NOT_ALLOWED
- EXTENSION_ASSET_REQUEST_INVALID
- Extension manifest not found: ${extensionId}
- Godot stage is not running.
- Godot stage bridge is not connected.
AI-assisted analysis of moeru-ai/airi@27111382b4 (2026-08-12).
Data as JSON: /api/errors/e2a2b5e5dac21c9a.
Report an issue: GitHub.