ComposioHQ/composio · error · Error
proxy fetch requires a non-empty URL string or URL object.
Error message
proxy fetch requires a non-empty URL string or URL object.
What it means
The proxied fetch requires the input to be a URL string or URL object that is non-empty after trimming. normalizeFetchInput throws when the endpoint resolves to undefined, a non-string, or blank text.
Source
Thrown at ts/packages/cli/src/services/run-helpers-runtime.ts:429
if (typeof body === 'string' || typeof body === 'number' || typeof body === 'boolean')
return body;
if (typeof Blob !== 'undefined' && body instanceof Blob) return await body.text();
if (body instanceof ArrayBuffer) return encodeBase64(new Uint8Array(body));
if (ArrayBuffer.isView(body)) {
return encodeBase64(new Uint8Array(body.buffer, body.byteOffset, body.byteLength));
}
return body;
};
const normalizeFetchInput = async (input: unknown, init: RequestInit = {}) => {
if (typeof Request !== 'undefined' && input instanceof Request) {
throw new Error(
'proxy() does not support passing a Request instance yet. Pass a URL string and init instead.'
);
}
const endpoint = input instanceof URL ? input.toString() : input;
if (typeof endpoint !== 'string' || endpoint.trim().length === 0) {
throw new Error('proxy fetch requires a non-empty URL string or URL object.');
}
const method = typeof init.method === 'string' ? init.method.toUpperCase() : 'GET';
if (!['GET', 'POST', 'PUT', 'DELETE', 'PATCH'].includes(method)) {
throw new Error('proxy fetch only supports GET, POST, PUT, DELETE, PATCH.');
}
return {
endpoint: endpoint.trim(),
method,
parameters: normalizeFetchHeaders(init.headers),
body: await normalizeFetchBody(init.body),
};
};
const toProxyResponse = async (result: ProxyExecuteResponse) => {
const headers = new Headers(result?.headers || {});
if (result?.binary_data?.url) {
const binaryResponse = await fetch(result.binary_data.url);
binaryResponse.headers.forEach((value, key) => {View on GitHub (pinned to 64b1b85502)
Solutions
- Pass a concrete URL string: proxy.fetch('https://api.example.com/endpoint')
- Validate/derive the URL before calling: if (!url) throw ...
- Use new URL(...) to construct and validate the URL earlier, catching malformed input sooner
Example fix
// before
await proxy.fetch(`${process.env.API_BASE}/x`); // API_BASE unset -> '/x' or 'undefined/x'
// after
const base = process.env.API_BASE;
if (!base) throw new Error('API_BASE is required');
await proxy.fetch(`${base}/x`); Defensive patterns
Strategy: validation
Validate before calling
if (typeof url !== 'string' || url.trim().length === 0) throw new TypeError('URL string required');
await proxy.fetch(url); Type guard
const isNonEmptyUrl = (v: unknown): v is string => typeof v === 'string' && v.trim().length > 0;
Prevention
- new URL(base) throws on malformed input — use it to validate early
- Never interpolate possibly-undefined env vars into URLs
When it happens
Trigger: Calling proxy.fetch(''), proxy.fetch(undefined), proxy.fetch(42), or passing a URL object whose toString() is empty.
Common situations: URL built from an unset env var producing '' or 'null', a template literal with an undefined interpolation, or passing an options object where a URL was expected.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- proxy fetch only supports GET, POST, PUT, DELETE, PATCH.
- proxy_execute: toolkit is required
- proxy_execute: endpoint is required
- proxy() requires a non-empty toolkit string.
- proxy() does not support passing a Request instance yet. Pas
AI-assisted analysis of ComposioHQ/composio@64b1b85502 (2026-08-28).
Data as JSON: /api/errors/9417720f81468bcb.
Report an issue: GitHub.