{"record":{"id":"91d6c4064e80522a","repo":"nexu-io/open-design","slug":"connector-output-too-large","errorCode":"CONNECTOR_OUTPUT_TOO_LARGE","errorMessage":"connector output exceeds max serialized size","messagePattern":"connector output exceeds max serialized size","errorType":"exception","errorClass":"ConnectorServiceError","httpStatus":502,"severity":"error","filePath":"apps/daemon/src/connectors/service.ts","lineNumber":552,"sourceCode":"      if (isForbiddenConnectorOutputKey(key)) {\n        next[key] = CONNECTOR_REDACTED_VALUE;\n        redacted = true;\n        continue;\n      }\n      const redactedChild = redactConnectorOutputValue(child);\n      next[key] = redactedChild.value;\n      redacted = redactedChild.redacted || redacted;\n    }\n    return { value: next, redacted };\n  }\n  return { value, redacted: false };\n}\n\nexport function protectConnectorOutput(output: BoundedJsonValue): ConnectorOutputProtectionResult {\n  const redacted = redactConnectorOutputValue(output);\n  const serializedBytes = jsonSerializedBytes(redacted.value);\n  if (serializedBytes > CONNECTOR_MAX_OUTPUT_BYTES) {\n    throw new ConnectorServiceError('CONNECTOR_OUTPUT_TOO_LARGE', 'connector output exceeds max serialized size', 502, {\n      maxSerializedBytes: CONNECTOR_MAX_OUTPUT_BYTES,\n      serializedBytes,\n    });\n  }\n  return { output: redacted.value, redacted: redacted.redacted, serializedBytes };\n}\n\nexport class ConnectorService {\n  private readonly runLimits = new Map<string, ConnectorRunLimitState>();\n\n  constructor(private readonly statusService = new ConnectorStatusService()) {}\n\n  setCredentialStore(credentialStore: ConnectorCredentialStore): void {\n    this.statusService.setCredentialStore(credentialStore);\n  }\n\n  deleteCredentialsByProvider(provider: string): void {\n    this.statusService.deleteCredentialsByProvider(provider);","sourceCodeStart":534,"sourceCodeEnd":570,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/apps/daemon/src/connectors/service.ts#L534-L570","documentation":"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.","triggerScenarios":"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().","commonSituations":"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.","solutions":["Narrow the tool input so the upstream returns fewer/smaller items (add filters, date ranges, or a smaller perPage).","Request only the fields you need if the tool supports field selection.","Paginate and aggregate client-side instead of fetching everything in one call.","If a genuine use case needs more, raise CONNECTOR_MAX_OUTPUT_BYTES in apps/daemon/src/connectors/service.ts after considering memory/bandwidth impact."],"exampleFix":"// before\nawait connectorService.execute(\n  { connectorId: 'github', toolName: 'list_repos', input: { perPage: 100 } },\n  ctx,\n);\n// provider returns >256KiB -> \"connector output exceeds max serialized size\"\n\n// after\nawait connectorService.execute(\n  { connectorId: 'github', toolName: 'list_repos', input: { perPage: 20, sort: 'updated' } },\n  ctx,\n);","handlingStrategy":"try-catch","validationCode":"import { CONNECTOR_MAX_OUTPUT_BYTES } from './connectors/service.js';\n\n// Estimate the serialized size of the request you expect to get back so you can\n// narrow the call before it ever trips the 256KiB cap.\nfunction estimateOutputBytes(payload: unknown): number {\n  return Buffer.byteLength(JSON.stringify(payload), 'utf8');\n}\n\n// Before execute, choose a perPage that keeps the expected result under the cap:\n// const trial = estimateOutputBytes(await previewList({ perPage: candidate }));\n// if (trial > CONNECTOR_MAX_OUTPUT_BYTES) candidate = Math.floor(candidate / 2);","typeGuard":null,"tryCatchPattern":"try {\n  return await connectorService.execute(request, ctx);\n} catch (error) {\n  if (error instanceof ConnectorServiceError && error.code === 'CONNECTOR_OUTPUT_TOO_LARGE') {\n    // details.serializedBytes vs details.maxSerializedBytes tell you how far over you are;\n    // narrow the request (smaller perPage / tighter filters) and retry once.\n    const narrower = { ...request, input: { ...request.input, perPage: Math.min(20, (request.input.perPage ?? 50) / 2 | 0 || 10) } };\n    return connectorService.execute(narrower, ctx);\n  }\n  throw error;\n}","preventionTips":["Default list-style tools to a modest perPage (10-25) and paginate rather than maxing out.","Apply filters/date ranges so the upstream returns only what you need.","Treat a single OUTPUT_TOO_LARGE as a signal to narrow scope, not to raise the global cap.","If a legitimate workflow needs more, evaluate raising CONNECTOR_MAX_OUTPUT_BYTES against daemon memory budget."],"tags":["connector","output","size-limit","composio","payload"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}