actualbudget/actual · warning
Invalid url parameter
Error message
Invalid url parameter
What it means
The proxy parses the supplied url query parameter with `new URL(...)`. If parsing throws (malformed URL), the proxy returns 400 'Invalid url parameter'. This catches syntactically invalid targets before any network work or allowlist checks happen.
Source
Thrown at packages/sync-server/src/app-cors-proxy.js:145
}
const targetUrlString = req.query.url;
if (!targetUrlString) {
return res.status(400).json({ error: 'Missing url parameter' });
}
// Validate session/token
const session = await validateSession(req, res);
if (!session) {
return; // validateSession already sent the response
}
let url;
try {
url = new URL(targetUrlString);
} catch {
return res.status(400).json({ error: 'Invalid url parameter' });
}
// Fetch the latest allowlist
try {
await fetchAllowlist();
} catch (error) {
console.error('Failed to fetch allowlist:', error);
return res.status(403).json({
error: 'URL not allowed',
message: 'Unable to verify allowlist',
});
}
// Check if the URL is allowed
if (!isUrlAllowed(url.href)) {
console.warn('Blocked request to unauthorized URL:', url.href);
return res.status(403).json({
error: 'URL not allowed',View on GitHub (pinned to d4334cb6e6)
Solutions
- Ensure the target is an absolute URL including the scheme (https://...) before encoding it into the query string.
- Run `new URL(target)` client-side to validate, and use encodeURIComponent when building the query.
- Log the raw url query value received by the server to spot encoding corruption.
Example fix
// before
const q = `/cors-proxy?url=${target}`; // unencoded
// after
const u = new URL(target); // throws early if invalid
const q = `/cors-proxy?url=${encodeURIComponent(u.href)}`; Defensive patterns
Strategy: validation
Validate before calling
let parsed;
try { parsed = new URL(target); } catch {
throw new Error(`Invalid proxy target: ${target}`);
}
if (!/^https?:$/.test(parsed.protocol)) throw new Error('Only http(s) targets are supported');
const proxied = `/cors-proxy?url=${encodeURIComponent(parsed.href)}`; Type guard
function isAbsoluteHttpUrl(s) {
try { const u = new URL(s); return u.protocol === 'http:' || u.protocol === 'https:'; }
catch { return false; }
} Try / catch
try {
return await proxy(target);
} catch (e) {
if (e.status === 400 && /Invalid url/.test(e.message)) {
console.error(`Target '${target}' is not a valid absolute URL`);
}
throw e;
} Prevention
- Always include the scheme (https://) in proxy targets.
- Validate with `new URL()` client-side before sending.
- Encode once — avoid double-encoding the target URL.
When it happens
Trigger: Passing a string without a scheme (e.g. url=example.com/list.json), a url with illegal characters from incomplete encoding, or a truncated/garbled query value.
Common situations: Forgetting the https:// scheme; double-encoding or not encoding the target so special characters (&, ?, spaces) corrupt the value; concatenating base URLs and paths incorrectly.
Related errors
- Missing url parameter
- Invalid method parameter
- Invalid --name: must be a non-empty string.
- No update fields provided. Use --name or --offbudget.
- Invalid cutoff date: expected a valid date (e.g. YYYY-MM-DD)
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/a7ff7896b7edd1e4.
Report an issue: GitHub.