microsoft/semantic-kernel · error · AgentInitializationException

Missing or malformed 'tool_connections' in: {spec}

Error message

Missing or malformed 'tool_connections' in: {spec}

What it means

Raised when building an azure_ai_search tool from a declarative ToolSpec and spec.options.tool_connections is absent, not a list, or an empty/falsy first element. tool_connections provides the Azure AI Search index connection ID and is mandatory.

Source

Thrown at python/semantic_kernel/agents/azure_ai/azure_ai_agent.py:105

_TOOL_BUILDERS: dict[str, Callable[[ToolSpec, Kernel | None], ToolDefinition]] = {}


def _register_tool(tool_type: str):
    def decorator(fn: Callable[[ToolSpec, Kernel | None], ToolDefinition]):
        _TOOL_BUILDERS[tool_type.lower()] = fn
        return fn

    return decorator


@_register_tool("azure_ai_search")
def _azure_ai_search(spec: ToolSpec) -> AzureAISearchTool:
    opts = spec.options or {}

    connections = opts.get("tool_connections")
    if not connections or not isinstance(connections, list) or not connections[0]:
        raise AgentInitializationException(f"Missing or malformed 'tool_connections' in: {spec}")
    conn_id = connections[0]

    index_name = opts.get("index_name")
    if not index_name or not isinstance(index_name, str):
        raise AgentInitializationException(f"Missing or malformed 'index_name' in: {spec}")

    raw_query_type = opts.get("query_type", AzureAISearchQueryType.SIMPLE)
    if type(raw_query_type) is str:
        try:
            query_type = AzureAISearchQueryType(raw_query_type.lower())
        except ValueError:
            raise AgentInitializationException(f"Invalid query_type '{raw_query_type}' in: {spec}")
    else:
        query_type = raw_query_type

    filter_expr = opts.get("filter", "")

    top_k = opts.get("top_k", 5)

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Add tool_connections as a list with the Azure AI Search index connection ID: tool_connections: ["/subscriptions/.../connection"]
  2. Ensure the connection ID is copied from the Azure AI project's Connections blade, not the search service URL.
  3. Validate the spec dict shape (list, non-empty, first element truthy) before passing to the agent factory.

Example fix

// before
tools:
  - type: azure_ai_search
    options:
      index_name: my-index

// after
tools:
  - type: azure_ai_search
    options:
      tool_connections:
        - "/subscriptions/.../projects/myproj/connections/mySearchConn"
      index_name: my-index
Defensive patterns

Strategy: validation

Validate before calling

def validate_ai_search_spec(spec_opts: dict) -> None:
    conns = spec_opts.get("tool_connections")
    if not isinstance(conns, list) or not conns or not conns[0]:
        raise ValueError("azure_ai_search requires non-empty list 'tool_connections'")

Type guard

def has_valid_connections(opts: dict) -> bool:
    c = opts.get("tool_connections")
    return isinstance(c, list) and bool(c) and bool(c[0])

Prevention

When it happens

Trigger: Declarative spec YAML/JSON omits tool_connections, provides it as a string instead of a list, or passes an empty list for an azure_ai_search tool.

Common situations: Developer hand-writes the declarative spec and forgets the connection ID; copies a template that used a placeholder; env-specific connection IDs not substituted.

Understand the failure class

Related errors


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/e933846c64803f65. Report an issue: GitHub.