chatboxai/chatbox · error · Error
builtin-provider-id-conflict
Error message
builtin-provider-id-conflict
What it means
Thrown by assertCustomProviderIdIsAvailable when importing/parsing a custom provider config whose id collides with a builtin provider id (isBuiltinProviderId returns true). The guard runs inside parseProviderConfig for any entry with isCustom === true, before the custom provider is registered, preventing builtin ids from being shadowed or overwritten.
Source
Thrown at src/renderer/utils/provider-config.ts:53
docs: z.string().optional(),
models: z.string().optional(),
})
.optional(),
settings: z.object({
apiHost: z.string(),
apiPath: z.string().optional(),
apiKey: z.string().optional(),
models: z.array(modelInfoSchema).optional(),
}),
})
const ProviderConfigSchema = z.union([BuiltinProviderConfigSchema, CustomProviderConfigSchema])
export type ProviderConfig = z.infer<typeof ProviderConfigSchema>
function assertCustomProviderIdIsAvailable(providerId: string): void {
if (isBuiltinProviderId(providerId)) {
throw new Error(CUSTOM_PROVIDER_ID_CONFLICT)
}
}
function parseProviderConfig(json: unknown): ProviderInfo | (ProviderSettings & { id: ModelProviderEnum }) | undefined {
if (json && typeof json === 'object' && 'isCustom' in json && json.isCustom === true) {
const parsedCustom = CustomProviderConfigSchema.parse(json)
assertCustomProviderIdIsAvailable(parsedCustom.id)
const providerType =
parsedCustom.type === 'openai'
? ModelProviderType.OpenAI
: parsedCustom.type === 'openai-responses'
? ModelProviderType.OpenAIResponses
: ModelProviderType.Claude
const providerInfo: ProviderInfo = {
id: parsedCustom.id,
name: parsedCustom.name,
type: providerType,View on GitHub (pinned to 81571269ad)
Solutions
- Rename the custom provider's id to something non-builtin (e.g. prefix with a namespace: 'myorg-openai') before importing.
- If you intend to override a builtin, use the builtin override mechanism (settings edit) rather than importing a custom entry with the same id.
- Audit the JSON being imported: check the 'id' field of each isCustom:true entry against the builtin id list.
- Improve the error to include the colliding id so the user knows which entry to rename.
Example fix
// before
function assertCustomProviderIdIsAvailable(providerId: string): void {
if (isBuiltinProviderId(providerId)) {
throw new Error(CUSTOM_PROVIDER_ID_CONFLICT)
}
}
// after — name the colliding id in the message
function assertCustomProviderIdIsAvailable(providerId: string): void {
if (isBuiltinProviderId(providerId)) {
throw new Error(`${CUSTOM_PROVIDER_ID_CONFLICT}: '${providerId}' is reserved`)
}
} Defensive patterns
Strategy: validation
Validate before calling
// Validate a custom-provider config import before passing to parseProviderConfig.
function assertCustomProviderImportSafe(json: unknown, isBuiltin: (id: string) => boolean): void {
if (json && typeof json === 'object' && (json as any).isCustom === true) {
const id = (json as any).id
if (typeof id === 'string' && isBuiltin(id)) {
throw new Error(`Rename custom provider id '${id}' — it collides with a builtin.`)
}
}
} Type guard
function isCustomProviderConfig(v: unknown): v is { isCustom: true; id: string } {
return typeof v === 'object' && v !== null &&
(v as any).isCustom === true && typeof (v as any).id === 'string'
} Try / catch
try {
registerProvider(parseProviderConfig(json))
} catch (e) {
if (e instanceof Error && e.message === CUSTOM_PROVIDER_ID_CONFLICT) {
promptUserToRenameProvider(json.id)
return
}
throw e
} Prevention
- Namespace custom provider ids (e.g. 'myorg-<name>') when generating config exports.
- Run import configs through a validator that lists collisions with builtin ids before registration.
- Improve the error to include the colliding id for faster remediation.
When it happens
Trigger: parseProviderConfig receives a JSON object with isCustom:true and an id that isBuiltinProviderId recognizes (e.g. 'openai', 'anthropic', 'chatbox-ai'). The custom config is rejected wholesale via CUSTOM_PROVIDER_ID_CONFLICT before any field is read.
Common situations: User imports a shared provider JSON whose author reused a builtin id; migrating a config between app versions where a previously-custom id became builtin; copy-paste of a builtin provider's exported JSON with isCustom flipped; third-party provider packs that don't namespace their ids.
Related errors
- Custom provider "${providerId}" conflicts with a builtin pro
- Backup JSON entry is too large: ${path}
- Manifest contains a duplicate path: ${descriptor.path}
- Invalid session entry: ${entry.path}
- Unsupported backup entry: ${entry.path}
AI-assisted analysis of chatboxai/chatbox@81571269ad (2026-08-12).
Data as JSON: /api/errors/9ce82f5e887024b0.
Report an issue: GitHub.