A search in a job search application I’m developing reported success without finding any usable postings. The workers were running, the task had finished, and the application reported no error. Unfortunately, the user wants job postings, not reassurance about the workers.

Finding nothing can be a perfectly valid result; the problem was that the application hadn’t established whether there was nothing to find. In the initial investigation, one external search source failed, and the fallback returned an HTTP 200 response. The inspected results were general references rather than the requested job postings. The request had received an answer, and the answer wasn’t useful.

The application turned a response with no eligible posting links into an empty candidate list. It then marked the task successful without distinguishing an empty search from an unusable response. Source troubles also disappeared as the result passed through storage to the interface, leaving the user with a generic success message. Each step lost a distinction the next step could have used.

An empty results tray can mean no matches, matches already saved, or an unavailable source.

That investigation used a synthetic public query. The exact responses from the earlier personal search hadn’t been retained, so it didn’t reconstruct that run, but it did show degraded source behavior and a path through the application that could turn it into apparent success.

“Nothing found” needs more than one explanation. Here are the distinctions I wanted to preserve:

What happenedWhat the application can tell the user
A source failed or returned unusable dataWe couldn’t check this source reliably.
A valid response contained no matchesThis source returned no postings matching the search.
Matching postings were already savedWe found matches, but nothing new to add.
Some sources or processing stages failedThese results cover only the work that completed.
New matches were savedThese postings are available to review.

These might overlap. A search could save useful matches and still have incomplete coverage because another source failed, and the interface should say both. Otherwise, a user may narrow or broaden a search to solve what is actually a source problem, or they might repeat a search because “nothing new” sounded like “nothing matched”.

Changing the final message won’t recover information the application has already discarded. The search needs to carry the outcome of each source check through to its stored result. It also needs to distinguish postings discovered, postings scored, and matches saved. If scoring fails, “zero saved matches” tells us about the interrupted process; it doesn’t tell us whether the postings would have been good matches. For older results that lack those measurements, “unavailable” is more accurate than an invented zero.

That changes the acceptance tests, too. A successful response containing irrelevant material fits the unusable-source case. A valid response explicitly reporting no results fits the empty case. If one source fails while another produces a match, the result should retain both facts, and a posting should count as saved only after saving succeeds. Checking only that the worker finished would miss all of those distinctions.

A subsequent staging check showed a narrower improvement: a posting reached scoring, scoring failed, and the interface displayed an explicit failure message that remained on the search page after the alert was dismissed. That was evidence that this failure was reported. It wasn’t evidence of reliable coverage or a successfully saved match.

When the application says it found nothing, the user needs to know whether to change the search, review existing matches, or wait for a source to recover. The result should give them enough information to make that decision.

—jhunterj

Join the conversation

Your email address will not be published. Required fields are marked *