ComposioHQ/composio · error · Error

proxy() does not support passing a Request instance yet. Pas

Error message

proxy() does not support passing a Request instance yet. Pass a URL string and init instead.

What it means

proxy()'s fetch passthrough (normalizeFetchInput) explicitly rejects Request instances. Only URL strings, URL objects, and a RequestInit-style init object are supported, because the proxy serializes endpoint/method/headers/body itself.

Source

Thrown at ts/packages/cli/src/services/run-helpers-runtime.ts:423

  });
  return normalized;
};

const normalizeFetchBody = async (body: unknown) => {
  if (body === undefined || body === null) return undefined;
  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),
  };
};

View on GitHub (pinned to 64b1b85502)

Solutions

  1. Pass the URL string (or URL object) plus an init object: proxy.fetch(url, { method, headers, body })
  2. Copy relevant fields off the Request (url, method, headers, body) into a plain init object

Example fix

// before
const req = new Request('https://api.example.com/x', { method: 'POST' });
await proxy.fetch(req);
// after
await proxy.fetch('https://api.example.com/x', { method: 'POST' });
Defensive patterns

Strategy: fallback

Validate before calling

if (typeof Request !== 'undefined' && input instanceof Request) {
  input = { url: input.url, init: { method: input.method, headers: [...input.headers], body: await input.text() } };
}

Type guard

const isRequestInstance = (v: unknown): v is Request => typeof Request !== 'undefined' && v instanceof Request;

Prevention

When it happens

Trigger: Calling proxy.fetch(new Request('https://example.com'), ...) or passing a Request built by another wrapper (e.g. a middleware) into the proxied fetch.

Common situations: Reusing code written for standard fetch that constructs Request objects; middleware/interceptor libraries that hand Request instances downstream.

Related errors


AI-assisted analysis of ComposioHQ/composio@64b1b85502 (2026-08-28). Data as JSON: /api/errors/7afb3bc3fde1db29. Report an issue: GitHub.