Skip to main content
Outlook Assistant · v3.7.1 minor release ·

Outlook Assistant v3.7.1 — Search That Tells You When It Lied

Outlook Assistant v3.7.1 fixes silent search-emails fallback on personal accounts and exposes searchMetadata so AI agents can detect when filters were dropped.

Highlights

No more silent unfiltered fallback

if filters match nothing in the target folder, the response now returns 0 results with actionable guidance — try searchAllFolders=true, check the folder name. Previously the agent saw recent unfiltered messages and drew wrong conclusions.

to filter works on personal accounts

Microsoft Graph's toRecipients/any() OData lambda fails silently on personal Outlook.com accounts. v3.7.1 adds a client-side fallback: fetches recent messages, filters by toRecipients locally.

query free-text fallback

when contains(subject) returns nothing for a free-text query, falls through to client-side body / subject / from search before giving up. The progressive-search claim that powers the product page is now actually true on personal accounts.

searchMetadata in _meta

every response carries _meta.searchMetadata with strategiesAttempted, finalStrategy, filterApplied, originalFilters. The agent can detect programmatically when a filter was dropped or which strategy actually matched.

What’s new in v3.7.1

This is one of those releases where the headline feature is “the thing that already worked now actually works.”

The silent-fallback bug

The original search-emails had a multi-strategy approach: try Microsoft Graph’s $search, fall back to $filter with contains(), fall back to client-side body search. Each strategy is supposed to either succeed or return zero results so the next one tries.

But on personal Outlook.com accounts, several Graph features fail silentlytoRecipients/any() returns 0 results without an error, $search works but doesn’t honour all field selectors, the API returns a 200 with an empty array. The previous fallback logic interpreted “0 results” as “no match, try the next strategy” — and the next strategy was unfiltered recent messages. So if you searched for emails to someone@example.com on a personal account, the response could be 25 recent unrelated messages, with no indication that the filter had been silently dropped.

The agent reading those 25 messages had no way to know. v3.7.1 fixes both halves: client-side fallback filters, and a searchMetadata block in the response so when a fallback ran, the agent knows.

Client-side fallbacks

For the to filter: when the Graph lambda expression returns 0 results on a personal account, the code now fetches the most recent messages from the target folder and filters them locally. This is the same pattern conversations.js has used for ages, just extended to search.

For free-text query: when contains(subject) returns nothing, it tries client-side body / subject / from matching against the recent message set before giving up. The “progressive search” feature card on the product page now actually maps to behaviour on personal accounts, not just work accounts.

searchMetadata

Every search response now carries _meta.searchMetadata. Four fields tell you exactly what happened: which strategies the code tried, which one returned the result, whether the filter you asked for actually ran, and what filters you sent in. If filterApplied: false, the agent knows the result set might not match what you asked. It can choose to retry, narrow the scope, or surface the limitation to you.

This was the bug that made me lose trust in my own tool for a few hours, and the fix took a week longer than I’d like to admit. Worth it.

Frequently asked questions

Why does search behave differently on personal vs work Microsoft accounts?
Microsoft Graph applies different feature flags by account type. Personal Outlook.com accounts don't support all the OData lambda expressions and search operators that work on Microsoft 365 work/school accounts. The to filter using toRecipients/any() is one such case — it returns no results without an error, so the previous silent fallback returned recent unfiltered messages and the agent assumed it had a real result set. v3.7.1 falls back to client-side filtering instead.
What does _meta.searchMetadata actually contain?
Four fields: strategiesAttempted (array of every strategy tried, in order), finalStrategy (the one that returned the result), filterApplied (true if the filter you asked for actually ran, false if a fallback ran instead), and originalFilters (echo of what you sent so the agent can compare). If filterApplied is false, the agent knows to either retry with different params or surface the limitation to you.
Will my existing search calls still work?
Yes. The signature is unchanged. v3.7.1 only changes what happens after the first strategy fails — instead of silently returning unfiltered results, it tries the client-side fallback or returns an empty result with guidance. Calls that were getting correct results before still get them; calls that were silently degrading now either succeed properly or report the gap.