actualbudget/actual · warning
Invalid method parameter
Error message
Invalid method parameter
What it means
The proxy accepts an optional JSON body where `method` specifies the HTTP verb to use for the proxied request. If method is present but not a string (e.g. a number or object), the proxy returns 400 'Invalid method parameter'. Only the type is checked here; allowed verbs are validated separately.
Source
Thrown at packages/sync-server/src/app-cors-proxy.js:173
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',
message:
'Only allowlisted plugin repositories are allowed (localhost only in development)',
});
}
try {
const { method = 'GET', headers: customHeaders = {} } = req.body || {};
if (typeof method !== 'string') {
return res.status(400).json({ error: 'Invalid method parameter' });
}
const methodNormalized = method.toUpperCase();
if (!['GET', 'HEAD'].includes(methodNormalized)) {
return res.status(405).json({ error: 'Method not allowed' });
}
const requestHeaders = {
...req.headers,
...customHeaders,
host: url.host,
};
// Remove headers that shouldn't be forwarded
delete requestHeaders['x-actual-token'];
delete requestHeaders['content-length'];
delete requestHeaders['cookie'];
delete requestHeaders['cookie2'];
View on GitHub (pinned to d4334cb6e6)
Solutions
- Send method as a string, e.g. { method: 'GET' }.
- Coerce/validate the method in the calling code: typeof method === 'string' || String(method).
- Omit the method field entirely to use the default 'GET'.
Example fix
// before
const body = { method: statusCode }; // number
// after
const body = { method: 'GET' }; // or String(method).toUpperCase() Defensive patterns
Strategy: type-guard
Validate before calling
const method = opts.method ?? 'GET';
if (typeof method !== 'string') throw new TypeError('method must be a string'); Type guard
function isMethodString(v) {
return typeof v === 'string';
} Try / catch
try {
return await proxy({ url, method });
} catch (e) {
if (e.status === 400 && /Invalid method/.test(e.message)) {
console.error('method must be a string like "GET"');
}
throw e;
} Prevention
- Always pass method as an uppercase string literal.
- Omit the method field to use the safe default 'GET'.
- Type the proxy options object (method?: string) to catch mistakes at compile time.
When it happens
Trigger: POSTing to the proxy with body { method: 200 } or { method: { ... } } — any non-string value for method.
Common situations: Auto-generated clients serializing method as a number (e.g. a status code); a config value passed through unvalidated; copy-pasted body using wrong field types.
Related errors
- Missing url parameter
- Invalid url 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/f807113ac8ea44c4.
Report an issue: GitHub.