langflow-ai/langflow · error · HTTPException

Created snapshot binding has empty tool_id={binding.tool_id!

Error message

Created snapshot binding has empty tool_id={binding.tool_id!r} or source_ref={binding.source_ref!r}; cannot map tool binding.

What it means

After a watsonx_orchestrate deployment update that creates new flow snapshots, the adapter returns created snapshot bindings and the mapper converts them into the API created_tools response. Each binding must carry both a non-empty tool_id (the wxO-owned tool id) and source_ref (the Langflow flow_version_id). If either is empty/blank after stripping, the binding cannot be mapped and HTTP 500 is raised — the provider or adapter returned malformed data.

Source

Thrown at src/backend/base/langflow/api/v1/mappers/deployments/watsonx_orchestrate/mapper.py:1799

            payload["display_name"] = display_name
        return payload

    def _to_api_created_tools(
        self,
        *,
        adapter_created_snapshot_bindings: list[Any],
    ) -> list[WatsonxApiCreatedTool]:
        """Map adapter created snapshot bindings to API ``created_tools``."""
        created_tools: list[WatsonxApiCreatedTool] = []
        for binding in adapter_created_snapshot_bindings:
            tool_id = str(binding.tool_id or "").strip()
            source_ref = str(binding.source_ref or "").strip()
            if not tool_id or not source_ref:
                msg = (
                    f"Created snapshot binding has empty tool_id={binding.tool_id!r} or "
                    f"source_ref={binding.source_ref!r}; cannot map tool binding."
                )
                raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=msg)
            try:
                created_tool = WatsonxApiCreatedTool(
                    flow_version_id=source_ref,
                    tool_id=tool_id,
                )
            except ValidationError as exc:
                msg = f"Created snapshot binding has non-UUID source_ref={source_ref!r} for tool_id={tool_id!r}."
                raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=msg) from exc
            created_tools.append(created_tool)
        return created_tools

    def _dump_key_value_connection_payloads(self, key_value_payloads: list[Any] | None) -> list[dict[str, Any]] | None:
        if not key_value_payloads:
            return None
        normalized: list[dict[str, Any]] = []
        for payload in key_value_payloads:
            item: dict[str, Any] = {"app_id": payload.app_id}
            environment_variables = self._to_adapter_environment_variables(payload.credentials)

View on GitHub (pinned to 976ec789d2)

Solutions

  1. Capture the raw adapter/wxO response (server logs) and verify what the provider actually returned for created snapshot bindings.
  2. If tool_id is empty because the provider hasn't assigned it yet, the adapter must wait/re-fetch before returning bindings — file an adapter issue.
  3. Check for a version mismatch between the wxO adapter and the watsonx_orchestrate API/region being targeted.
  4. Retry the update: if the snapshot was in fact created, a follow-up update may re-sync bindings; otherwise clean up orphaned tools in wxO.
Defensive patterns

Strategy: try-catch

Type guard

def is_valid_binding(binding) -> bool:
    return bool(str(getattr(binding, "tool_id", "") or "").strip()) and bool(str(getattr(binding, "source_ref", "") or "").strip())

Try / catch

try:
    created = await client.patch(f"/api/v1/deployments/{id}", json=body)
except HTTPError as e:
    if e.response.status_code == 500 and "empty tool_id" in e.response.text:
        # provider-side partial success: audit wxO for orphaned tools before retrying
        log.error("adapter returned malformed created bindings; check wxO tools")
    raise

Prevention

When it happens

Trigger: Deployment update succeeds on the wxO side but the adapter's created-snapshot binding payload contains an empty tool_id or source_ref; mapping the response then fails with 500.

Common situations: wxO API version change altering the binding payload shape; adapter bug or partial response; race where the provider returns a binding before assigning the tool id. Not caused by anything the API caller sent.

Related errors


AI-assisted analysis of langflow-ai/langflow@976ec789d2 (2026-08-14). Data as JSON: /api/errors/8c746287d94f03fb. Report an issue: GitHub.