iOfficeAI/AionUi · error · Error
update.errors.invalidUrl
update.errors.invalidUrl
Error message
update.errors.invalidUrl
What it means
Thrown by assertAllowedUrl in the update bridge when the URL string passed to the updater cannot be parsed by the URL constructor. It is the first validation step before protocol and host checks, so any syntactically invalid URL (empty string, missing scheme, malformed characters) triggers it.
Source
Thrown at packages/desktop/src/process/bridge/updateBridge.ts:275
prerelease: false,
draft: false,
assets,
recommendedAsset: pickRecommendedAsset(assets),
};
};
const resolveRepo = (requestRepo?: string): string => {
const envRepo = process.env.AIONUI_GITHUB_REPO?.trim();
const repo = (requestRepo || envRepo || DEFAULT_REPO).trim();
return repo || DEFAULT_REPO;
};
const assertAllowedUrl = async (rawUrl: string) => {
let parsed: URL;
try {
parsed = new URL(rawUrl);
} catch {
throw new Error((await getI18n()).t('update.errors.invalidUrl'));
}
if (parsed.protocol !== 'https:') {
throw new Error((await getI18n()).t('update.errors.httpsOnly'));
}
if (!ALLOWED_DOWNLOAD_HOSTS.has(parsed.hostname)) {
throw new Error((await getI18n()).t('update.errors.hostNotAllowed', { host: parsed.hostname }));
}
};
const fetchWithAllowlistedRedirects = async (rawUrl: string, signal: AbortSignal): Promise<Response> => {
let current = rawUrl;
for (let i = 0; i <= MAX_REDIRECTS; i++) {
await assertAllowedUrl(current);
const res = await fetch(current, {
signal,View on GitHub (pinned to 711aa0550e)
Solutions
- Check the URL string being passed — it must be a fully qualified absolute URL
- Add the https:// scheme if it is missing
- Trim whitespace/newlines from config-sourced URLs before passing them
- Reset or fix the stored update configuration if it was corrupted
- Log the raw value before the call to identify where the bad string originates
Example fix
// before
await assertAllowedUrl(feedUrl); // feedUrl = 'example.com/app.json'
// after
const normalized = feedUrl.trim();
await assertAllowedUrl(
/^https?:\/\//.test(normalized) ? normalized : `https://${normalized}`,
); Defensive patterns
Strategy: validation
Validate before calling
const isValidAbsoluteUrl = (s: string): boolean => {
try {
const u = new URL(s.trim());
return u.protocol === 'http:' || u.protocol === 'https:';
} catch {
return false;
}
};
if (!isValidAbsoluteUrl(feedUrl)) throw new Error('configure a valid https update URL');
await initUpdateBridge(feedUrl); Type guard
const isParsableUrl = (v: unknown): v is string =>
typeof v === 'string' &&
(() => { try { new URL(v.trim()); return true; } catch { return false; } })(); Try / catch
try {
await assertAllowedUrl(url);
} catch (err) {
if (err instanceof Error && err.message.includes('invalidUrl')) {
// sanitize: trim, prepend https:// if scheme missing, then retry
} else throw err;
} Prevention
- Always store fully-qualified https URLs in update config
- Trim config-sourced URLs before use
- Fail fast in settings UI when the URL field cannot be parsed by new URL()
- Never build feed URLs from possibly-undefined template variables
When it happens
Trigger: Calling any update API that funnels through assertAllowedUrl (fetchWithAllowlistedRedirects, runWithFallback, initUpdateBridge) with a non-URL string: '', 'github.com/owner/repo' (no scheme), 'https://' alone, or a URL with invalid control characters.
Common situations: A misconfigured update feed URL in settings/config that omits https://; a template string that evaluated to undefined and became 'undefined'; trailing whitespace or newline in a config-provided URL; corrupted persisted app config after an upgrade.
Related errors
- update.errors.httpsOnly
- update.errors.hostNotAllowed
- update.errors.redirectNoLocation
- update.errors.tooManyRedirects
- update.errors.githubApiFailed
AI-assisted analysis of iOfficeAI/AionUi@711aa0550e (2026-08-28).
Data as JSON: /api/errors/b424c682af772ea9.
Report an issue: GitHub.