nexu-io/open-design · error · ConnectorServiceError

CONNECTOR_OUTPUT_TOO_LARGE

CONNECTOR_OUTPUT_TOO_LARGE

Error message

connector output exceeds max serialized size

What it means

Thrown by protectConnectorOutput() after a connector tool executes successfully: the provider's output is redacted, serialized to JSON, and if it exceeds CONNECTOR_MAX_OUTPUT_BYTES (256 * 1024 = 262144 bytes) a ConnectorServiceError is raised with code CONNECTOR_OUTPUT_TOO_LARGE and HTTP 502. It caps memory/bandwidth abuse from chatty upstream tools and surfaces maxSerializedBytes/serializedBytes in details.

Source

Thrown at apps/daemon/src/connectors/service.ts:552

      if (isForbiddenConnectorOutputKey(key)) {
        next[key] = CONNECTOR_REDACTED_VALUE;
        redacted = true;
        continue;
      }
      const redactedChild = redactConnectorOutputValue(child);
      next[key] = redactedChild.value;
      redacted = redactedChild.redacted || redacted;
    }
    return { value: next, redacted };
  }
  return { value, redacted: false };
}

export function protectConnectorOutput(output: BoundedJsonValue): ConnectorOutputProtectionResult {
  const redacted = redactConnectorOutputValue(output);
  const serializedBytes = jsonSerializedBytes(redacted.value);
  if (serializedBytes > CONNECTOR_MAX_OUTPUT_BYTES) {
    throw new ConnectorServiceError('CONNECTOR_OUTPUT_TOO_LARGE', 'connector output exceeds max serialized size', 502, {
      maxSerializedBytes: CONNECTOR_MAX_OUTPUT_BYTES,
      serializedBytes,
    });
  }
  return { output: redacted.value, redacted: redacted.redacted, serializedBytes };
}

export class ConnectorService {
  private readonly runLimits = new Map<string, ConnectorRunLimitState>();

  constructor(private readonly statusService = new ConnectorStatusService()) {}

  setCredentialStore(credentialStore: ConnectorCredentialStore): void {
    this.statusService.setCredentialStore(credentialStore);
  }

  deleteCredentialsByProvider(provider: string): void {
    this.statusService.deleteCredentialsByProvider(provider);

View on GitHub (pinned to 5be4028344)

Solutions

  1. Narrow the tool input so the upstream returns fewer/smaller items (add filters, date ranges, or a smaller perPage).
  2. Request only the fields you need if the tool supports field selection.
  3. Paginate and aggregate client-side instead of fetching everything in one call.
  4. If a genuine use case needs more, raise CONNECTOR_MAX_OUTPUT_BYTES in apps/daemon/src/connectors/service.ts after considering memory/bandwidth impact.

Example fix

// before
await connectorService.execute(
  { connectorId: 'github', toolName: 'list_repos', input: { perPage: 100 } },
  ctx,
);
// provider returns >256KiB -> "connector output exceeds max serialized size"

// after
await connectorService.execute(
  { connectorId: 'github', toolName: 'list_repos', input: { perPage: 20, sort: 'updated' } },
  ctx,
);
Defensive patterns

Strategy: try-catch

Validate before calling

import { CONNECTOR_MAX_OUTPUT_BYTES } from './connectors/service.js';

// Estimate the serialized size of the request you expect to get back so you can
// narrow the call before it ever trips the 256KiB cap.
function estimateOutputBytes(payload: unknown): number {
  return Buffer.byteLength(JSON.stringify(payload), 'utf8');
}

// Before execute, choose a perPage that keeps the expected result under the cap:
// const trial = estimateOutputBytes(await previewList({ perPage: candidate }));
// if (trial > CONNECTOR_MAX_OUTPUT_BYTES) candidate = Math.floor(candidate / 2);

Try / catch

try {
  return await connectorService.execute(request, ctx);
} catch (error) {
  if (error instanceof ConnectorServiceError && error.code === 'CONNECTOR_OUTPUT_TOO_LARGE') {
    // details.serializedBytes vs details.maxSerializedBytes tell you how far over you are;
    // narrow the request (smaller perPage / tighter filters) and retry once.
    const narrower = { ...request, input: { ...request.input, perPage: Math.min(20, (request.input.perPage ?? 50) / 2 | 0 || 10) } };
    return connectorService.execute(narrower, ctx);
  }
  throw error;
}

Prevention

When it happens

Trigger: A Composio tool returns a very large payload (long list, full file contents, verbose logs) that, even after redactConnectorOutputValue redaction, serializes to more than 256 KiB. The error originates in execute() at service.ts:823 via protectConnectorOutput().

Common situations: Listing endpoints with no limit (list all repos/issues/comments); a tool returning a base64-encoded attachment; verbose error objects from the upstream provider; a query with an over-broad filter.

Related errors


AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12). Data as JSON: /api/errors/91d6c4064e80522a. Report an issue: GitHub.