AI Tutorials

An Empty AI Search Is Not Evidence That Nothing Exists

An assistant can return no matches before its search is finished. Check scope, continuation, partial failures and time before allowing a negative answer to close a task.

An Empty AI Search Is Not Evidence That Nothing Exists
Written by
ZharfAI Team
Published
September 23, 2026
Reading time
12 minutes

A service assistant checks for an existing maintenance request before opening another. Its search tool returns an empty list. The assistant writes, “No request exists,” and creates a duplicate. The missing record was on a later page; the first page contained records that the tool filtered out.

This is a constructed example, not a ZharfAI customer incident. It illustrates a decision for enterprise-search developers and operations owners: when may an assistant report a bounded absence, and when must it continue, qualify its answer or hand the task back? Correctly quoting the returned list is not enough. The tool must also explain what that list leaves unresolved.

Name the set before claiming it is empty

“No contract exists” hides several questions. In which repository? For which legal entity? Under which employee's access? Does the query include archived documents, attachments and historical versions? Does “contract” mean a structured record type or any document whose text describes an agreement?

Define the population and the predicate separately. The population might be authorized maintenance records for one site. The predicate might be an exact equipment identifier, an open status and a specified date interval. A search for similar words is a different operation, even if both tools have the same friendly name in chat.

Our design recommendation is to distinguish three statements: “I found this matching record,” “the defined query completed without a match,” and “the search has not established an answer.” The second statement is narrower than “nothing exists.” It says nothing about an unconnected archive or information the source never recorded.

For consequential questions, put the agreed scope in the tool request and the final answer. Do not silently widen a failed search to another tenant, identity or repository. If the requested population cannot be described without ambiguity, clarification is part of the work, not a search failure to conceal.

An empty page is not an end-of-search signal

Microsoft Graph's paging guide explicitly allows pages with zero results and describes continuation through the complete @odata.nextLink URL until that property is absent. It also warns that required custom headers on directory queries must be supplied again on subsequent requests. A connector that only preserves the rows can lose both continuation and query context.

DynamoDB's Query reference documents an especially clear case: filtering happens after records are read. A response can contain no items and still carry LastEvaluatedKey. A nonempty key does not promise another matching item; it means the client has not yet established exhaustion.

These are provider contracts, not instructions to implement one universal cursor loop. Each adapter must understand its own endpoint. Do not stop because a page is empty, because it is shorter than the requested size, or because the model feels it has searched enough. Conversely, do not keep calling forever: an exhausted budget is an explicit incomplete outcome.

Successful transport can carry incomplete evidence

The response body matters after the HTTP request succeeds. Google Drive's v3 list reference separates nextPageToken from incompleteSearch. The latter warns that some documents were not searched, including a possible multi-drive case. Finishing the available pages does not repair that separate limitation. Narrowing the corpus may help, but it also changes what the answer covers.

Elasticsearch's search API likewise exposes partial-result behavior, timeouts and shard failures. Its timed_out flag can accompany partial or empty results. A negative-answer path should inspect those signals, not treat a readable response as proof of completion.

The architectural lesson is to carry failure and completeness information beside the evidence. Do not turn a connector exception into an empty array for UI convenience. That conversion erases the difference between “none matched” and “we could not check.” If a legacy tool returns only rows, its empty output is insufficient for an absence claim until the missing semantics are supplied elsewhere.

Keep continuation state in the connector, not the conversation

Use a deterministic adapter to own page traversal. Let the model propose the business question and explain a checked outcome; do not ask it to reconstruct cursor strings from previous chat turns. Truncated context, rewritten filters and forgotten headers should not determine which records are examined.

For each run, preserve a compact record of the source, authorized identity context, normalized query, filters, ordering, requested scope, start time and any source snapshot identifier. Keep raw credentials and sensitive continuation values out of the model transcript. The model usually needs a run identifier and an honest outcome, not transport internals.

The adapter should validate each response, retain source-specific continuation state, and combine evidence without losing stable record identifiers. It should detect a repeated continuation state, enforce total page/time/byte budgets, and finish with a reason. “Completed,” “budget exhausted,” “source error,” “scope incomplete” and “snapshot lost” must not collapse into one Boolean success flag.

Retries need endpoint-specific handling. A failed page must not advance the cursor or mark traversal complete. Where restart is required, start a new traversal generation; do not combine fragments from two generations and label them one complete search. De-duplicating repeated identifiers can make a result usable, but it cannot prove that no identifiers were skipped.

This is a proposed integration pattern, not a product feature guaranteed by any of the cited platforms. It makes incomplete work visible while keeping implementation details out of the user's question.

A completed traversal still needs a time boundary

Records can move while pages are being read. Offset-based traversal over a changing order can skip an item or return it twice. A stable sort helps with ordering, but it does not by itself freeze the underlying collection.

Elasticsearch's pagination guidance describes using search_after with a point in time to preserve index state, and requires appropriate tie-breaking and unchanged query/sort semantics. This protects traversal within that search system. It does not prove that the index contains every upstream document.

The boundary is different in a database. PostgreSQL 18's isolation documentation explains that Read Committed uses a new snapshot for each statement, whereas successive reads in one Repeatable Read transaction share a snapshot established by its first non-transaction-control statement. Neither mechanism creates a common snapshot across unrelated services.

Choose the claim your application can support. An index may be complete for its own snapshot but behind the source. A live API may support complete traversal without promising a single frozen collection. Record that difference. Where consistency cannot support the required decision, use an authoritative bounded query or decline the stronger conclusion.

The guide to time semantics explains why source time, observation time and decision time belong in separate fields. Here, those fields limit the validity of a negative answer. A completed check at 09:00 cannot prove that a record was not created at 09:01.

Follow a five-record example through three pages

Consider a synthetic DynamoDB-style query over one equipment partition, sorted by record identifier. The fixture contains five tiny records, IDs 1–5. IDs 1–4 are closed; ID 5 is open. The query evaluates at most two records per call and filters for open status after reading. Assume no concurrent changes and no size limit reached before that two-record limit.

PageRecords evaluatedMatching records returnedContinuation in this fixture
First1 and 2, both closedNonePresent, after ID 2
Second3 and 4, both closedNonePresent, after ID 4
Third5, openID 5Absent

A loop driven by the length of the first result list stops before it sees ID 5. A traversal driven by the response's continuation state reaches it. The two empty pages are neither errors nor evidence of an empty partition. The third page supplies a positive witness: an existing open request.

Change the fixture so ID 5 is closed too. The same traversal now ends with no match. Under the stipulated static data, correct scope and exact predicate, that supports “no open request matched in this partition.” Stop after page two for a time budget, however, and the outcome is incomplete in both versions of the fixture.

These are test inputs and expected outcomes, not observed cloud-service results. Production tests should verify the real adapter and its SDK behavior separately. The useful invariant is independent of page size: zero returned matches cannot turn an unfinished traversal into a completed negative answer.

Ranked retrieval answers a different question

A retrieval-augmented assistant often receives a handful of highly ranked passages, not a complete list. Those passages may support a positive statement when the underlying source and interpretation check out. Their silence cannot establish that no exception, amendment or contradictory record exists elsewhere.

Separate “find useful evidence” from “enumerate every record satisfying this predicate.” The first task can often stop when sufficient supporting material is found. The second needs a defined collection and an exact or independently validated selection rule. Increasing the number of retrieved passages improves an opportunity to find evidence; it does not automatically convert ranked search into exhaustive enumeration.

Even an exhausted keyword query proves only that query's result, not a semantic absence. A Persian document may describe a renewal without using the chosen word. An attachment may never have been extracted. A metadata field may be missing rather than false. Before concluding, decide whether the predicate actually represents the business question.

The RAG knowledge-quality guide covers extraction, chunking and evidence quality. The data-quality and observability guide addresses missing upstream data. They are complementary controls: perfect pagination cannot repair an incomplete index, and an excellent index cannot repair a client that stops on page one.

Match the answer and the next action to the evidence

Treat result content, traversal status and scope fitness as separate dimensions. A partial run can contain a valid matching record, but not necessarily every match. A complete run can still answer the wrong question. One status named “success” obscures both distinctions.

Evidence availableAppropriate responseNext step
Valid matching record, incomplete traversal“I found this record; the list may be incomplete.”Verify the record and continue only if the task requires all matches
No match, continuation or unresolved failure“I have not completed the check.”Resume within budget, retry safely, or hand back
Query exhausted, but scope or predicate inadequate“Nothing matched this query; it does not settle your question.”Clarify scope or use a more authoritative search
Query exhausted, scope and time boundary fit the task“No match was found in this defined collection at this boundary.”Use the bounded result under the workflow's action policy

This table is ZharfAI's design recommendation. The wording should name limitations without implying that inaccessible records do or do not exist. Do not expose hidden object counts merely to make an explanation look complete.

Finding no duplicate also does not reserve the right to create a new record. Another worker might create one between the check and the write. For a create-if-absent workflow, enforce the relevant uniqueness or transactional rule at the write boundary. Search evidence informs the decision; it is not a concurrency lock or a replacement for action authorization.

Test the negative answers, not just the successful lookups

Build controlled fixtures with an empty intermediate page, a match only on the final page, a repeated cursor, a timeout after useful results, an incomplete-search flag without continuation, and a token that requires restart. Test omitted completion fields too: if an adapter's response projection drops them, the result should become unknown rather than complete by default.

Add a changing-source test, an expired snapshot, an access change and a query whose text filter misses a known synonym. These exercise different claims. Do not count a traversal test as proof of semantic recall, or a language test as proof that the connector visited all pages. Include final answer wording in acceptance tests so qualifiers survive summarization.

For a small owned corpus, independently define the expected matching IDs and compare them with the complete traversal. Log the run ID, query version, scope reference, page count, stop reason and supported time boundary. Apply retention and access controls to those records; copying all retrieved documents into debug logs creates unnecessary exposure.

Monitor the share of negative answers backed by adequate completion evidence, unfinished searches by stop reason, repeated continuations, and known matches missed in seeded tests. Measure latency and cost alongside these outcomes. Do not advertise a real-world false-absence rate unless an independent process establishes the missing-record ground truth.

Revisit the adapter when an SDK, endpoint, projection, permission model, indexing process or ordering rule changes. A useful assistant is allowed to say that its check is unfinished. What it should not do is make unfinished work disappear behind a confident “none.”

Source notes — reviewed September 23, 2026

This guide synthesizes provider contracts and proposes application-level controls; it is not a certification of any connector or a report of a ZharfAI deployment. The worked fixture is synthetic.

#Enterprise Search#AI Reliability#Pagination#Data Completeness#Retrieval

Related Posts

Name one process for a discovery call

If this note maps to a real system in your organisation, start with the services page or a shipped case study.