different-ai/openwork · error
Update connection access response was incomplete.
Error message
Update connection access response was incomplete.
What it means
The update-connection-access mutation assigns `result = input.connectionId` inside the runReauthableAction callback after a successful fetch. The connectionId is a local value, so `result` can only be falsy if the callback never ran to completion (e.g. re-auth wrapper resolved without executing) or connectionId was empty/undefined in the input. The guard surfaces that as a thrown error rather than silently resolving the mutation.
Source
Thrown at ee/apps/den-web/app/(den)/dashboard/_components/mcp-connections-data.tsx:867
export function useReplaceMcpConnectionAccess() {
const queryClient = useQueryClient();
const { orgId, runReauthableAction } = useOrgDashboard();
return useMutation({
mutationFn: async (input: { connectionId: string; access: McpConnectionAccessInput }): Promise<string> => {
let result: string | null = null;
await runReauthableAction("replace-mcp-connection-access", async () => {
const { response, payload } = await requestJson(
`/v1/mcp-connections/${encodeURIComponent(input.connectionId)}/access`,
{ method: "PUT", headers: getOrgScopeHeaders(requireOrgId(orgId)), body: JSON.stringify({ access: input.access }) },
15000,
);
if (!response.ok) {
throw getRequestError(payload, response, `Failed to update connection access (${response.status}).`);
}
result = input.connectionId;
});
if (!result) throw new Error("Update connection access response was incomplete.");
return result;
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: mcpConnectionQueryKeys.all });
},
});
}
export function useStartMcpConnectionOAuth() {
const { orgId } = useOrgDashboard();
return useMutation({
mutationFn: async (connectionId: string): Promise<{ status: "connected" | "needs_auth"; authorizeUrl: string | null }> => {
const { response, payload } = await requestJson(
`/v1/mcp-connections/${encodeURIComponent(connectionId)}/connect/start`,
{ headers: getOrgScopeHeaders(requireOrgId(orgId)) },
20000,
);View on GitHub (pinned to 2b7df46e8a)
Solutions
- Validate input.connectionId is a non-empty string before calling mutateAsync
- Confirm runReauthableAction re-executes its callback after successful re-auth and throws (not silently resolves) on dismissal
- Log the callback execution to see whether the fetch+assignment path ran
- Check that the access-toggle endpoint's 2xx response isn't short-circuiting the assignment
Example fix
// before
if (!result) throw new Error("Update connection access response was incomplete.");
// after
if (!result) {
throw new Error(`Update connection access: no connectionId (input.connectionId=${JSON.stringify(input.connectionId)}).`);
} Defensive patterns
Strategy: validation
Validate before calling
function assertConnectionAccessInput(input: { connectionId: string; access: 'private' | 'shared' }) {
if (!input.connectionId) throw new Error('connectionId is required before updating access');
if (!['private', 'shared'].includes(input.access)) throw new Error(`invalid access: ${input.access}`);
} Type guard
function hasConnectionId(v: unknown): v is { connectionId: string } {
return isRecord(v) && typeof v.connectionId === 'string' && v.connectionId.length > 0;
} Try / catch
try {
await updateAccess.mutateAsync({ connectionId, access });
} catch (e) {
showToast({ variant: 'error', title: 'Could not change access', description: e instanceof Error ? e.message : String(e) });
queryClient.invalidateQueries({ queryKey: mcpConnectionQueryKeys.all });
} Prevention
- Disable access toggles for rows without a stable connectionId
- Refetch the connection list before mutating after long idle periods
- Keep wrapper callback-execute-once semantics
- Test the expired-session + cancelled re-auth path
When it happens
Trigger: mutateAsync on update connection access with input.connectionId undefined/empty string, or runReauthableAction resolving without re-running the callback after an auth prompt was dismissed.
Common situations: UI passed a stale/missing connectionId after a list refetch removed the row; expired Den session triggered re-auth that was cancelled; wrapper contract change after refactor.
Understand the failure class
Background: "empty response", "returned no data", "empty embeddings": what HTTP 200-with-empty-body errors mean across libraries — this error's family across 36 libraries.
Related errors
- Update MCP connection response was incomplete.
- OAuth issuer review response was incomplete.
- Disconnect MCP connection response was incomplete.
- Delete MCP connection response was incomplete.
- The dashboard response was invalid.
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/98db2fa4a0d51595.
Report an issue: GitHub.