invoke-ai/InvokeAI · error · DuplicateModelException
Model key '{key}' already exists. Provide a different key to
Error message
Model key '{key}' already exists. Provide a different key to install this external model. What it means
_register_external_model() checks the record store before registering an external (provider-API) model under a caller-supplied key. If a model with that key already exists, it raises DuplicateModelException asking for a different key. This guard exists because external model keys are caller-chosen, so collisions must be caught explicitly.
Source
Thrown at invokeai/app/services/model_install/model_install_default.py:1036
existing_external = next(
(
model
for model in self.record_store.search_by_attr(
base_model=BaseModelType.External, model_type=ModelType.ExternalImageGenerator
)
if isinstance(model, ExternalApiModelConfig)
and model.provider_id == provider_id
and model.provider_model_id == provider_model_id
),
None,
)
if existing_external is not None:
key = existing_external.key
else:
try:
self.record_store.get_model(key)
raise DuplicateModelException(
f"Model key '{key}' already exists. Provide a different key to install this external model."
)
except UnknownModelException:
pass
config = ExternalApiModelConfig(
key=key,
name=name,
description=job.config_in.description,
provider_id=provider_id,
provider_model_id=provider_model_id,
capabilities=capabilities,
default_settings=default_settings,
source=str(job.source),
source_type=MODEL_SOURCE_TO_TYPE_MAP[job.source.__class__],
path="",
hash="",
file_size=0,View on GitHub (pinned to 0b6a024f2f)
Solutions
- Omit the 'key' field in ModelRecordChanges and let the service generate a unique key.
- Generate a fresh unique key (e.g. from the source id + hash) before installing.
- If the model is intentionally the same, look it up first and skip re-installation.
- Use install_or_update-style flows that update an existing model instead of registering a duplicate.
Example fix
// before config = ModelRecordChanges(source=source, key='my-sdxl') # collides // after config = ModelRecordChanges(source=source) # let service assign a unique key service.install(config)
Defensive patterns
Strategy: try-catch
Validate before calling
from invokeai.app.services.shared.sqlite.sqlite_common import UnknownModelException
key_collision = False
try:
service.record_store.get_model(key)
key_collision = True
except UnknownModelException:
pass Try / catch
try:
service.install(ModelRecordChanges(source=src, key=key))
except DuplicateModelException:
existing = service.record_store.get_model(key) # already installed; update or skip Prevention
- Omit the 'key' field and let the service generate unique keys.
- Treat installs as idempotent: look up before inserting.
- Avoid hard-coded keys shared across scripts/environments.
- Serialize external-model installs to avoid concurrent key races.
When it happens
Trigger: Calling _register_or_install/install with ModelRecordChanges containing a 'key' that already exists in the record store; installing the same external model twice with the same hard-coded key; restoring from a store that already contains the key.
Common situations: Scripts that install external models idempotently but reuse a fixed key without checking first; two concurrent installs with the same key; copying install commands between environments sharing a database.
Related errors
- Failed to remove image from board
- Failed to add images to board
- Failed to remove images from board
- Failed to create board
- Board not found
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/baf1c6d55c3357b5.
Report an issue: GitHub.