tinyhumansai/openhuman · error

Channel connect response missing status

Error message

Channel connect response missing status

What it means

Thrown by normalizeConnectResult() when the 'openhuman.channels_connect' response object has no string 'status' field (status is read, coerced to '' when not a string, and the empty value throws). Connect results may carry optional restart_required/auth_action/message, but status is the one mandatory field the connect UI branches on.

Source

Thrown at app/src/services/api/channelConnectionsApi.ts:103

}

function expectDiscordLinkComplete(payload: unknown): DiscordLinkCheckResult {
  const record = expectObject<Record<string, unknown>>(payload, 'Discord link complete');
  if (typeof record.linked !== 'boolean') {
    throw new Error('Discord link complete response missing required boolean field: linked');
  }
  const details =
    record.details !== undefined && record.details !== null
      ? (record.details as Record<string, unknown>)
      : null;
  return { linked: record.linked, details };
}

function normalizeConnectResult(payload: unknown): ChannelConnectionResult {
  const record = expectObject<Record<string, unknown>>(payload, 'Channel connect');
  const status = typeof record.status === 'string' ? record.status : '';
  if (!status) {
    throw new Error('Channel connect response missing status');
  }
  return {
    status,
    restart_required: Boolean(record.restart_required),
    auth_action: typeof record.auth_action === 'string' ? record.auth_action : undefined,
    message: typeof record.message === 'string' ? record.message : undefined,
  };
}

function normalizePermissionCheck(payload: unknown): BotPermissionCheck {
  const record = expectObject<Record<string, unknown>>(payload, 'Discord permission check');
  const missing = Array.isArray(record.missing_permissions)
    ? record.missing_permissions.filter((perm): perm is string => typeof perm === 'string')
    : [];
  return {
    can_view_channel: Boolean(record.can_view_channel),
    can_send_messages: Boolean(record.can_send_messages),
    can_read_message_history: Boolean(record.can_read_message_history),

View on GitHub (pinned to a221052e0d)

Solutions

  1. Restart the core / relaunch the app so both halves are the same build
  2. Reproduce with curl: openhuman.channels_connect with the same channel/authMode/credentials and inspect the result object
  3. Check the core logs for the specific channel's connect handler path — the shape is per-channel, so identify which channel produced it
  4. If developing the handler, map every exit path to a status string ('connected', 'failed', 'restart_required', ...)

Example fix

// before
{"success": false, "message": "bad token"}

// after
{"status": "failed", "message": "bad token", "restart_required": false}
Defensive patterns

Strategy: type-guard

Type guard

function isConnectResult(v: unknown): v is { status: string; restart_required?: boolean; auth_action?: string; message?: string } {
  const r = v as Record<string, unknown> | null | undefined;
  const inner =
    r && 'result' in r && 'logs' in r ? (r.result as Record<string, unknown>) : r;
  return !!inner && typeof inner.status === 'string' && inner.status.length > 0;
}

Try / catch

try {
  const res = await channelConnectionsApi.connectChannel(channel, payload);
  handleStatus(res.status);
} catch (e) {
  if (e instanceof Error && e.message.includes('missing status')) {
    showConnectError('Unexpected core response — update/restart the app and retry.');
  } else throw e;
}

Prevention

When it happens

Trigger: connectChannel(channel, payload) resolves with a payload whose status is missing, null, or non-string — e.g. the core returned {success: false, message: '...'} instead of a status-bearing result, or a CLI envelope whose inner result lacks status.

Common situations: Core/frontend contract drift after updating one side only; a channel whose connect handler short-circuits with a differently-shaped object (per-channel handlers differ); channel compiled out by a feature gate returning a stub shape.

Related errors


AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16). Data as JSON: /api/errors/56344229f3a02618. Report an issue: GitHub.