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
- Keep the retry_filter registered (kernel.add_filter(FilterTypes.FUNCTION_INVOCATION, retry_filter)) so the simulated failures are retried until success.
- Lower MAX_FAILURES to 0 to make get_weather succeed immediately when you no longer want the simulated flakiness.
- Catch the Exception at the call site if you intentionally want to observe the failure.
- 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
- Keep the retry_filter registered while MAX_FAILURES > 0.
- Set MAX_FAILURES = 0 when adapting the sample to a real, reliable service.
- Replace the generic Exception with a realistic transient exception type for production code.
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
- User stopped the operation
- Invalid operator
- No chart generated
- Invalid filename: would write outside the expected directory
- No chart generated
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/f4538ac69d3051fa.
Report an issue: GitHub.