invoke-ai/InvokeAI · info · HTTPException
str(e) (ValueError, relationship already exists)
Error message
str(e) (ValueError, relationship already exists)
What it means
HTTP 409 raised when the model relationships service throws ValueError because the exact bidirectional relationship between the two keys already exists. Since relationships are unique unordered pairs, adding the same pair twice collides.
Source
Thrown at invokeai/app/api/routers/model_relationships.py:132
) -> None:
"""
Add a relationship between two models.
Relationships are bidirectional and will be accessible from both models.
- Raises 400 if keys are invalid or identical.
- Raises 409 if the relationship already exists.
"""
if req.model_key_1 == req.model_key_2:
raise HTTPException(status_code=400, detail="Cannot relate a model to itself.")
try:
ApiDependencies.invoker.services.model_relationships.add_model_relationship(
req.model_key_1,
req.model_key_2,
)
except ValueError as e:
raise HTTPException(status_code=409, detail=str(e))
@model_relationships_router.delete(
"/",
status_code=status.HTTP_204_NO_CONTENT,
responses={
204: {"description": "The relationship was successfully removed"},
400: {"description": "Invalid model keys or self-referential relationship"},
404: {"description": "The relationship does not exist"},
422: {"description": "Validation error"},
500: {"description": "Internal server error"},
},
summary="Remove Model Relationship",
description="Removes a **bidirectional** relationship between two models. The relationship must already exist.",
)
def remove_model_relationship(
current_user: AdminUserOrDefault,
req: ModelRelationshipCreateRequest = Body(..., description="The model keys to disconnect"),View on GitHub (pinned to 0b6a024f2f)
Solutions
- Treat 409 as success (the relationship exists) and continue
- Before adding, call GET related-models for one key and skip pairs already present
- Deduplicate the input pair list and use 'add or ignore' logic in scripts
- Wrap the call so ValueError/409 is swallowed but other errors propagate
Example fix
// before
await api.addRelationship({ model_key_1: a, model_key_2: b });
// after
try {
await api.addRelationship({ model_key_1: a, model_key_2: b });
} catch (e) {
if (e.status !== 409) throw e; // already related — fine
} Defensive patterns
Strategy: try-catch
Validate before calling
const existing = new Set(await api.getRelatedModels(key1));
if (existing.has(key2)) {
console.log('already related');
} else {
await api.addRelationship({ model_key_1: key1, model_key_2: key2 });
} Try / catch
try {
await api.addRelationship({ model_key_1: a, model_key_2: b });
} catch (e) {
if (e.status === 409) return; // idempotent no-op
throw e;
} Prevention
- Treat 'already exists' as success in scripts
- Check existing relationships before adding
- Debounce/duplicate-guard the relate button in UIs
When it happens
Trigger: POST /api/v1/models/relationships with a (key1, key2) pair that was already related in either order; duplicate form submissions; scripts that don't check for existing relationships before adding.
Common situations: Re-running an idempotency-breaking sync script; double-clicking the 'relate' button; importing a relationships list that contains duplicates.
Related errors
- str(e) (Exception during conversion)
- Cannot relate a model to itself.
- Cannot unlink a model from itself.
- str(e) (ValueError, relationship not found)
- str(e)
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/b2e9ee3ac32116a6.
Report an issue: GitHub.