QuantumNous/new-api · warning · Error
You don't have necessary permission
Error message
You don't have necessary permission
What it means
Thrown by formPreviewFetcher in the channel drawer when canEditSensitive is false. Fetching the upstream model list can leak the channel key, so the UI refuses to build the preview request for users without sensitive-field edit permission; the error propagates to the fetch-models dialog.
Source
Thrown at web/src/features/channels/components/drawers/channel-mutate-drawer.tsx:1462
toast.error(t("You don't have necessary permission"))
return
}
// Advanced Custom may use a model discovery route with no authentication.
if (!isEditing && type !== CHANNEL_TYPE_ADVANCED_CUSTOM) {
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.dataView on GitHub (pinned to e2c7aa7b10)
Solutions
- Hide or disable the fetch-models button when canEditSensitive is false instead of letting the fetcher throw
- Grant the account sensitive-edit permission if it should manage channel keys/models
- Re-login/refresh after permission changes so the UI re-evaluates canEditSensitive
- If you are root and still see this, check that the permission computation (role flags) is intact
Example fix
// before
<Button onClick={() => setFetchModelsDialogOpen(true)}>Fetch models</Button>
// after
<Button disabled={!canEditSensitive} onClick={() => setFetchModelsDialogOpen(true)}>
Fetch models
</Button> Defensive patterns
Strategy: validation
Validate before calling
if (!canEditSensitive) return // hide/disable the fetch-models action entirely
Type guard
const canFetchModelList = ( canEditSensitive: boolean, isEditing: boolean, type: number, channelId: number | null ): boolean => canEditSensitive && !(isEditing && type === CHANNEL_TYPE_ADVANCED_CUSTOM && channelId == null)
Prevention
- Derive button visibility from canEditSensitive instead of throwing in the fetcher
- Recompute permissions on session refresh so stale flags do not survive role changes
- Keep the fetcher's throw as defense in depth, not the primary gate
When it happens
Trigger: A non-root/limited admin (or a user whose role strips sensitive-edit permission) opens the 'fetch models' preview in the channel drawer; the permission check fails before any API call is made.
Common situations: Logged in as a viewer/limited admin; permission changed server-side after the page loaded (stale UI); root delegated channel management but not key visibility.
Related errors
- No channel selected
- 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/bdba52023567c8dd.
Report an issue: GitHub.