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
- Ensure the edit drawer always receives the channel's id from the selected row
- Reset and re-open the drawer from the channel table so state initializes correctly
- Guard the UI: disable fetch-models when editingAdvancedCustom && channelId == null
- 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
- Always pass the row's id when opening the drawer in edit mode
- Disable fetch-models for advanced custom channels until channelId is loaded
- Use != null checks so both null and undefined ids trip the guard
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
- You don't have necessary permission
- No models fetched from upstream
- Failed to update channel
- Failed to create channel
- Failed to fetch usage
AI-assisted analysis of QuantumNous/new-api@e2c7aa7b10 (2026-08-15).
Data as JSON: /api/errors/13389a79c1550d76.
Report an issue: GitHub.