different-ai/openwork · error · DenApiError
invalid_mcp_connection_payload
invalid_mcp_connection_payload
Error message
MCP connection connect response was invalid.
What it means
DenApiError thrown by startMcpConnectionConnect in apps/app/src/app/lib/den.ts when the Den API returned a 2xx for GET /v1/mcp-connections/{connectionId}/connect/start, but the response body failed the getDenMcpConnectionConnectStart shape check (missing or malformed connect-start data such as an OAuth authorize URL / session info). The client refuses to return unvalidated data rather than passing a partially-shaped object downstream.
Source
Thrown at apps/app/src/app/lib/den.ts:3394
async listMcpConnectionPresets(orgId: string): Promise<DenExternalMcpPreset[]> {
const payload = await requestJson<unknown>(
baseUrls,
"/v1/mcp-connections/presets",
{ method: "GET", token, organizationId: orgId },
);
return getDenExternalMcpPresets(payload);
},
async startMcpConnectionConnect(orgId: string, connectionId: string): Promise<DenMcpConnectionConnectStart> {
const payload = await requestJson<unknown>(
baseUrls,
`/v1/mcp-connections/${encodeURIComponent(connectionId)}/connect/start`,
{ method: "GET", token, organizationId: orgId },
);
const result = getDenMcpConnectionConnectStart(payload);
if (!result) {
throw new DenApiError(500, "invalid_mcp_connection_payload", "MCP connection connect response was invalid.");
}
return result;
},
async disconnectOauthProviderAccount(orgId: string, providerId: string): Promise<void> {
await requestJson<unknown>(
baseUrls,
`/v1/oauth-providers/${encodeURIComponent(providerId)}/disconnect`,
{ method: "POST", token, organizationId: orgId },
);
},
async disconnectMyMcpConnectionAccount(orgId: string, connectionId: string): Promise<void> {
await requestJson<unknown>(
baseUrls,
`/v1/mcp-connections/${encodeURIComponent(connectionId)}/disconnect-my-account`,
{ method: "POST", token, organizationId: orgId },
);View on GitHub (pinned to 2b7df46e8a)
Solutions
- Log the raw response body from /v1/mcp-connections/:id/connect/start and compare it against the fields getDenMcpConnectionConnectStart expects
- Verify the Den server version matches the client: a schema mismatch means upgrade the server or align the client
- Confirm the connectionId is valid, exists in the org, and is in a connectable state (list via /v1/mcp-connections first)
- Check no proxy/gateway/CDN is rewriting the JSON response into HTML or a login page
- Retry after re-authenticating if the token silently fell back to an anonymous/limited session
Example fix
// before
const result = getDenMcpConnectionConnectStart(payload);
if (!result) {
throw new DenApiError(500, "invalid_mcp_connection_payload", "MCP connection connect response was invalid.");
}
// after
defensive on caller side:
try {
const start = await client.startMcpConnectionConnect(orgId, connectionId);
} catch (err) {
if (err instanceof DenApiError && err.code === "invalid_mcp_connection_payload") {
// inspect raw payload / refresh connection list before retrying
}
} Defensive patterns
Strategy: try-catch
Validate before calling
// client-side pre-check before starting connect
const conns = await client.listMcpConnections(orgId);
const conn = conns.find((c) => c.id === connectionId);
if (!conn) throw new Error(`Unknown MCP connection: ${connectionId}`); Type guard
function isConnectStart(v: unknown): v is DenMcpConnectionConnectStart {
return (
typeof v === "object" && v !== null &&
"authorizeUrl" in v && typeof (v as { authorizeUrl?: unknown }).authorizeUrl === "string"
);
} Try / catch
try {
const start = await client.startMcpConnectionConnect(orgId, connectionId);
} catch (err) {
if (err instanceof DenApiError && err.code === "invalid_mcp_connection_payload") {
// surface 'connect flow unavailable' and let the user retry after refreshing connections
} else { throw err; }
} Prevention
- Always resolve connectionId from listMcpConnections rather than persisted/stale values
- Pin matching client/server versions of the Den API
- Log raw response bodies for /connect/start in dev to catch schema drift early
- Check for proxies or service workers that can rewrite API responses
- Catch DenApiError by code so payload-shape failures degrade gracefully instead of crashing the connect UI
When it happens
Trigger: GET /v1/mcp-connections/:id/connect/start returned 200 but the body was an empty object, an error envelope, HTML from a proxy, or lacked the fields getDenMcpConnectionConnectStart requires (e.g. no authorizeUrl/session data); typically when the connectionId exists but the connection is not in a connectable state or the server version's payload schema differs.
Common situations: Pointing the app at a self-hosted or older Den server whose /connect/start endpoint predates the current response schema; a reverse proxy or gateway intercepting the request and returning a 200 page; passing a deleted or wrong-organization connectionId; middleware (mock server, service worker) returning a stubbed body.
Related errors
- invalid_marketplace_payload
- invalid_plugin_payload
- invalid_billing_payload
- The MCP provider did not return an authorization URL.
- Failed to configure plugin connection (${response.status}).
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/32cb17de54ad574e.
Report an issue: GitHub.