moeru-ai/airi · error · Error
The Base URL is not an absolute http:// or https:// address.
Error message
The Base URL is not an absolute http:// or https:// address.
What it means
request() builds the target URL with `new URL(...)` via buildUrl; if that throws (base is relative, empty, or a non-http scheme), the library rethrows this error. The engine client requires an absolute http:// or https:// Base URL because the browser/renderer fetch cannot resolve engine-relative paths.
Source
Thrown at packages/stage-ui/src/libs/providers/providers/voicevox/engine.ts:189
const body = await response.text()
try {
return JSON.parse(body) as T
}
catch {
throw new Error(`Speech engine answered /${endpoint} with a body that is not JSON. Check that the Base URL points at a VOICEVOX-compatible engine.`)
}
}
async function request(
engineRequest: VoicevoxEngineRequest,
options?: VoicevoxEngineRequestOptions,
): Promise<Response> {
let url: URL
try {
url = buildUrl(engineRequest)
}
catch {
throw new Error('The Base URL is not an absolute http:// or https:// address.')
}
const doFetch = options?.fetch ?? globalThis.fetch
const response = await doFetch(url, {
method: POST_ENDPOINTS.has(engineRequest.endpoint) ? 'POST' : 'GET',
// No engine in the family redirects. A redirect therefore means the Base URL
// points at something else, and following it would hide that.
redirect: 'error',
signal: options?.signal,
...(engineRequest.body === undefined
? {}
: { body: JSON.stringify(engineRequest.body), headers: { 'Content-Type': 'application/json' } }),
})
if (!response.ok) {
const detail = (await response.text()).trim()
const suffix = detail ? `: ${detail.slice(0, 200)}` : ''
throw new Error(`Speech engine answered ${response.status} ${response.statusText} for /${engineRequest.endpoint}${suffix}`)View on GitHub (pinned to 9c213115f8)
Solutions
- Set the Base URL to a full absolute URL including scheme, e.g. `http://127.0.0.1:50021` or `https://voicevox.example.com`.
- If using a local engine on https-only pages, proxy it or use `http://localhost:50021` where allowed.
- Trim whitespace and re-check the scheme when saving the settings field.
Example fix
// before baseUrl: 'localhost:50021' // after baseUrl: 'http://localhost:50021'
Defensive patterns
Strategy: validation
Validate before calling
function isAbsoluteHttpUrl(value: string): boolean {
try {
const url = new URL(value)
return url.protocol === 'http:' || url.protocol === 'https:'
}
catch {
return false
}
}
if (!isAbsoluteHttpUrl(baseUrl))
throw new Error('Base URL must be an absolute http:// or https:// address') Type guard
function isHttpUrl(value: unknown): value is string {
if (typeof value !== 'string')
return false
try {
return ['http:', 'https:'].includes(new URL(value).protocol)
}
catch {
return false
}
} Prevention
- Validate the Base URL field with an absolute-URL check at settings save time.
- Show a hint/placeholder in the settings UI like `http://127.0.0.1:50021`.
- Never build engine URLs by string concatenation on relative paths.
When it happens
Trigger: Base URL configured as a relative path like `localhost:50021` (no scheme) or `/voicevox`, an empty string, or a scheme like `ws://`/`file://` — anything that makes `new URL(path, base)` throw or not be http(s).
Common situations: User typed the host without `http://`; trailing config value left empty after clearing a default; settings field trimmed of scheme; pasting a URL from docs that omitted the scheme.
Related errors
- Invalid speech request body
- No voice selected. Pick a character in the speech settings.
- Speech engine answered /${endpoint} with a body that is not
- Provider definition with id "${definitionId}" not found.
- Aliyun NLS credentials are incomplete.
AI-assisted analysis of moeru-ai/airi@9c213115f8 (2026-09-02).
Data as JSON: /api/errors/65da30bb119f7f80.
Report an issue: GitHub.