QuantumNous/new-api · warning · Error

No channel selected

Error message

No channel selected

What it means

Thrown by formPreviewFetcher when editing an advanced-custom channel (isEditing && type === CHANNEL_TYPE_ADVANCED_CUSTOM) but channelId is null. Fetching models for advanced custom channels must be proxied through the saved channel (channel_id), so a missing id is rejected before calling fetchModels.

Source

Thrown at web/src/features/channels/components/drawers/channel-mutate-drawer.tsx:1468

      const key = form.getValues('key')
      if (!key?.trim()) {
        toast.error(t('Please enter API key first'))
        return
      }
    }

    setFetchModelsDialogOpen(true)
  }, [isEditing, canEditSensitive, form, t])

  const formPreviewFetcher = useCallback(async (): Promise<string[]> => {
    if (!canEditSensitive) {
      throw new Error(t("You don't have necessary permission"))
    }
    const type = form.getValues('type')
    const editingAdvancedCustom =
      isEditing && type === CHANNEL_TYPE_ADVANCED_CUSTOM
    if (editingAdvancedCustom && channelId === null) {
      throw new Error(t('No channel selected'))
    }
    const response = await fetchModels({
      type,
      key: isEditing ? undefined : form.getValues('key'),
      channel_id: editingAdvancedCustom ? channelId || undefined : undefined,
      base_url: form.getValues('base_url') || '',
      advanced_custom: form.getValues('advanced_custom'),
      header_override: form.getValues('header_override'),
      proxy: form.getValues('proxy'),
    })
    if (response.success && response.data) {
      return response.data
    }
    throw new Error(response.message || t('No models fetched from upstream'))
  }, [canEditSensitive, channelId, form, isEditing, t])

  // Handle model operations
  const handleFillRelatedModels = useCallback(() => {

View on GitHub (pinned to e2c7aa7b10)

Solutions

  1. Ensure the edit drawer always receives the channel's id from the selected row
  2. Reset and re-open the drawer from the channel table so state initializes correctly
  3. Guard the UI: disable fetch-models when editingAdvancedCustom && channelId == null
  4. Verify the parent passes a number id (not a string 'undefined'/'null' from URL params)

Example fix

// before
if (editingAdvancedCustom && channelId === null) {
  throw new Error(t('No channel selected'))
}
// after - prevent reaching the fetcher at all
const canFetchModels =
  canEditSensitive &&
  !(editingAdvancedCustom && channelId == null)
// <Button disabled={!canFetchModels} ...>
Defensive patterns

Strategy: validation

Validate before calling

const editingAdvancedCustom = isEditing && type === CHANNEL_TYPE_ADVANCED_CUSTOM
if (editingAdvancedCustom && channelId == null) {
  toast.error(t('No channel selected'))
  return
}

Type guard

const hasSavedChannel = (id: number | null | undefined): id is number =>
  typeof id === 'number' && id > 0

Prevention

When it happens

Trigger: Edit-mode drawer for an advanced custom channel where the id prop was not provided or was reset to null (e.g. state reused from create mode), then the user opens the fetch-models preview.

Common situations: Drawer opened programmatically without the row id; create/edit mode switch left channelId null; id lost during a refactor of the drawer's props.

Related errors


AI-assisted analysis of QuantumNous/new-api@e2c7aa7b10 (2026-08-15). Data as JSON: /api/errors/13389a79c1550d76. Report an issue: GitHub.