microsoft/semantic-kernel · info · Exception

Failed to get the weather

Error message

Failed to get the weather

What it means

Exception raised deliberately by the sample WeatherPlugin.get_weather for its first MAX_FAILURES invocations, to simulate a flaky external service so the accompanying retry_filter can demonstrate exponential backoff. Once _invocation_count reaches MAX_FAILURES, it returns 'Sunny' instead. It is intentional simulated failure, not a real error path.

Source

Thrown at python/samples/concepts/filtering/retry_with_filters.py:45


class WeatherPlugin:
    MAX_FAILURES = 2

    def __init__(self):
        self._invocation_count = 0

    @kernel_function(name="GetWeather", description="Get the weather of the day at the current location.")
    def get_weather(self) -> str:
        """Get the weather of the day at the current location.

        Simulates a call to an external service to get the weather.
        This function is designed to fail a certain number of times before succeeding.
        """
        if self._invocation_count < self.MAX_FAILURES:
            self._invocation_count += 1
            print(f"Number of attempts: {self._invocation_count}")
            raise Exception("Failed to get the weather")

        return "Sunny"


async def retry_filter(
    context: FunctionInvocationContext,
    next: Callable[[FunctionInvocationContext], Awaitable[None]],
) -> None:
    """A filter that retries the function invocation if it fails.

    The filter uses a binary exponential backoff strategy to retry the function invocation.
    """
    for i in range(MAX_RETRIES):
        try:
            await next(context)
            return
        except Exception as e:
            logger.warning(f"Failed to execute the function: {e}")

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Keep the retry_filter registered (kernel.add_filter(FilterTypes.FUNCTION_INVOCATION, retry_filter)) so the simulated failures are retried until success.
  2. Lower MAX_FAILURES to 0 to make get_weather succeed immediately when you no longer want the simulated flakiness.
  3. Catch the Exception at the call site if you intentionally want to observe the failure.
  4. Replace the simulated Exception with a realistic transient exception type if adapting the sample to a real service.

Example fix

# before - always fails MAX_FAILURES times
class WeatherPlugin:
    MAX_FAILURES = 3
    def get_weather(self):
        if self._invocation_count < self.MAX_FAILURES:
            self._invocation_count += 1
            raise Exception("Failed to get the weather")
        return "Sunny"
# after - disable simulated failure for real use
class WeatherPlugin:
    MAX_FAILURES = 0
    def get_weather(self):
        return "Sunny"
Defensive patterns

Strategy: retry

Validate before calling

# If you do NOT want simulated failure, set MAX_FAILURES = 0 before invoking.
plugin = WeatherPlugin()
plugin.MAX_FAILURES = 0   # disables simulated flakiness
# otherwise ensure the retry_filter is registered so failures are retried

Type guard

def will_succeed_now(plugin) -> bool:
    return plugin._invocation_count >= getattr(plugin, "MAX_FAILURES", 0)

Try / catch

# Mirror the sample's retry_filter at your own call site if you drop the filter.
for attempt in range(MAX_RETRIES):
    try:
        result = await kernel.invoke(weather_func)
        break
    except Exception as e:
        await asyncio.sleep(2 ** attempt)
else:
    raise

Prevention

When it happens

Trigger: Invoking the WeatherPlugin.GetWeather kernel function while _invocation_count < MAX_FAILURES. Each such call increments the counter, prints the attempt number, and raises Exception('Failed to get the weather').

Common situations: Running the retry_with_filters sample; the first one or two calls always raise by design. If you remove or disable the retry_filter, this exception will propagate to the caller instead of being retried.

Related errors


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