langflow-ai/langflow · error · ValueError
{remove_label} cannot be combined with upsert for the same i
Error message
{remove_label} cannot be combined with upsert for the same id: {conflicts} What it means
API payload validator: an id that is being removed outright (remove_flows / remove_tools) must not also appear in the upsert lists (upsert_flows[].flow_version_id / upsert_tools[].tool_id). Combining remove with upsert for the same id is contradictory; ValueError '{remove_label} cannot be combined with upsert for the same id' is raised, surfacing as 422.
Source
Thrown at src/backend/base/langflow/api/v1/mappers/deployments/watsonx_orchestrate/payloads.py:249
def _validate_api_remove_conflicts(
*,
remove_ids: list[Any],
upsert_operations: list[Any],
remove_label: str,
upsert_attr_name: str,
) -> None:
normalized_remove_ids = {str(remove_id).strip() for remove_id in remove_ids if str(remove_id).strip()}
normalized_upsert_ids = {
str(getattr(operation, upsert_attr_name, "")).strip()
for operation in upsert_operations
if str(getattr(operation, upsert_attr_name, "")).strip()
}
conflicts = sorted(normalized_remove_ids.intersection(normalized_upsert_ids))
if conflicts:
msg = f"{remove_label} cannot be combined with upsert for the same id: {conflicts}"
raise ValueError(msg)
def _validate_api_unused_raw_app_ids(*, raw_app_ids: set[str], referenced_app_ids: set[str]) -> None:
unused_raw_app_ids = sorted(raw_app_ids.difference(referenced_app_ids))
if unused_raw_app_ids:
msg = f"connections contains app_id values not referenced by operations: {unused_raw_app_ids}"
raise ValueError(msg)
def _validate_api_unique_connection_app_ids(*, connections: list[WatsonxApiKeyValueConnectionPayload]) -> None:
app_id_counts = Counter(connection.app_id for connection in connections)
duplicates = sorted(app_id for app_id, count in app_id_counts.items() if count > 1)
if duplicates:
msg = f"connections contains duplicate app_id values: {duplicates}"
raise ValueError(msg)
class WatsonxApiDeploymentUpdatePayload(BaseModel):View on GitHub (pinned to 976ec789d2)
Solutions
- Pick one action per id: to delete it put it only in remove_flows/remove_tools; to modify it put it only in the upsert list.
- Rebuild the payload from a single source of truth (current deployment state + user intent) so each id lands in exactly one bucket.
- Validate client-side: assert disjointness between remove ids and upsert ids before sending.
Example fix
// before
{"upsert_flows": [{"flow_version_id": "fv1", ...}], "remove_flows": ["fv1"]}
// after
{"remove_flows": ["fv1"]} Defensive patterns
Strategy: validation
Validate before calling
upsert_fv = {str(i["flow_version_id"]) for i in provider_data.get("upsert_flows", [])}
remove_fv = {str(fv) for fv in provider_data.get("remove_flows", [])}
assert upsert_fv.isdisjoint(remove_fv)
upsert_t = {i["tool_id"] for i in provider_data.get("upsert_tools", [])}
remove_t = set(provider_data.get("remove_tools", []))
assert upsert_t.isdisjoint(remove_t) Type guard
def no_remove_upsert_conflict(provider_data: dict) -> bool:
for upsert_key, remove_key, id_attr in (("upsert_flows", "remove_flows", "flow_version_id"), ("upsert_tools", "remove_tools", "tool_id")):
upsert_ids = {str(i.get(id_attr)) for i in provider_data.get(upsert_key, [])}
if upsert_ids & {str(r) for r in provider_data.get(remove_key, [])}:
return False
return True Prevention
- Build each id's intent exactly once from current state + user action.
- Assert remove lists are disjoint from upsert lists before sending.
- Do not concatenate independent update and delete payloads.
When it happens
Trigger: PATCH a wxO deployment whose provider_data includes remove_flows containing a UUID that also appears as some upsert_flows[].flow_version_id, or remove_tools containing a tool_id also present in upsert_tools.
Common situations: UI allowing 'edit and delete' simultaneously; request built by concatenating an update payload and a delete payload; stale state where a client re-upserts a flow it just queued for removal.
Related errors
- String must not be empty.
- credentials contains duplicate key values: {sorted(duplicate
- {label} must not reference connections app_ids: {invalid_raw
- {label} add_app_ids and remove_app_ids must not overlap: {ov
- connections contains app_id values not referenced by operati
AI-assisted analysis of langflow-ai/langflow@976ec789d2 (2026-08-14).
Data as JSON: /api/errors/afd455fa57ddbe02.
Report an issue: GitHub.