Some websites hide links that no person can see, so any visit marks a bot. Cloudflare’s AI Labyrinth works this way1. Scraping guides tell bot builders to draw the page like a browser and skip hidden links2. A defender wants to know which agents a trap catches without running them.
Whether an agent sees the link depends on its fetch tool, the program that turns a web page into text for the model. In our earlier test, three small agents had to find a 2025 number on websites we built3. The table page showed only 2024 numbers, and a hidden footer link led to the answer. They followed it in 99% of runs when its words fit the task (“Full 2025 pricing table”). We call a link whose words do not fit the task an off-task link (“Office photo gallery archive”). They followed one in 3% to 73% of runs. But they used fetch tools we wrote.
Here we test a simple rule on ten shipped fetch tools. A link is exposed when the tool’s first reply for a page holds its address, or a button the agent can press. The rule predicts the follow rate as the share of pages that expose the link, times the agent’s earlier rate. Among the ten tools is the MCP fetch tool, the official fetch tool of the Model Context Protocol, a standard way to give agents tools. By default, it runs what we call a main-text filter. The filter keeps a page’s article text and usually drops menus and footers. The tool also has a raw mode that the agent can switch on. Raw mode returns the page’s full code, hidden parts included.
We ask: does a crawl with no model predict how often AI agents follow a hidden link?
TLDR; No. The MCP fetch tool’s default reply drops a fully hidden link, so the crawl predicted no follows. But agents switched the same tool to raw mode and followed the link in 54 of 90 runs. For GPT-5.4 mini’s off-task link, the crawl predicted 73% both in raw mode and in Browser Use, an open-source browsing agent. Mini took the link in 45 of 60 runs and in 19 of 60. Yes needed at most one clear miss, and the crawl had six. Its average error was still only 9 points. The published claims “every bot sees hidden links” and “browser-style tools avoid them” were off by 39 and 27.
Filled pink dots are clear misses, and ringed ones are smaller misses or too close to call. In the top two groups, most sit above the band: agents reached the link through raw mode or a page the crawl did not read. In the third group, two of the three are GPT-5.4 mini’s off-task link.
How we tested it
We reused the earlier test’s five websites. We hid the footer link in three ways: fully hidden (display:none), shrunk to one pixel, or moved off the screen. A script with no model crawled every tool first. Then we froze the predictions and ran the same three agents. A follow is a request for the run’s own random link address in our server log. A Yes needed at most one clear miss: a gap over 10 points even at the near end of its 95% range.
One scraping guide says to skip one-pixel links. Browser Use shows them as normal buttons. Turndown, a markdown converter, first runs the same main-text filter as the MCP fetch tool.
What we found
The crawl failed in two separate ways. Each one alone answers the title with No.
First, the tool offers a second route. A crawl can see that the MCP fetch tool has a raw mode, but not how often agents use it. With the fully hidden link, agents switched to raw mode and followed it. GPT-5.4 mini did so in 24 of 30 runs, nano in 21, Flash-Lite in 9. Most switched after the table page showed only 2024 numbers (37 of 57 switches). As in our earlier test, stuck agents went looking. Our earlier post said agents with the MCP fetch tool never meet the trap, because its default reply drops the link. Raw mode makes that wrong.
Second, the layout changes how often an agent takes a shown off-task link. Only GPT-5.4 mini takes it often enough to show this. The crawl predicted 73% in all three tools. Mini followed the link in 45 of 60 runs in raw mode. It followed it in 24 of 60 in crawl4ai, another markdown converter, and in 19 of 60 in Browser Use’s page view. Other work found that page format changes how often models obey planted text4.
Should you trust our results?
- We ran three small agents on five small websites we built, with the link in the footer only.
- The crawl read two pages per site. It did not read a blog page where the main-text filter kept the footer link, on 4 of 5 sites. On one site, 12 of 18 Turndown runs with the fitting link followed it there.
- Fitting links on fully exposed pages got only 2 or 3 runs per pair (60 of 62 followed), except in Browser Use (58 of 60).
- We gave Browser Use three of its actions: navigate, click and scroll. Its other actions may reach links its page view drops.
So, does a crawl with no model predict how often AI agents follow a hidden link? No. The crawl tells you which tools show the link. It cannot tell how often agents take a second route, or how the layout moves an off-task follow. Our written prediction failed too (box under the title).
To us it is clear that a defender should crawl first, then run agents wherever a tool offers a second route. For tool builders: a raw mode undoes the main-text filter.
Details for experts
- Agents: GPT-5.4 nano, GPT-5.4 mini and Gemini 3.1 Flash-Lite through their APIs, at the provider’s default temperature. The system prompt, task wordings, sites and 8-step limit are the earlier test’s, unchanged. The agent starts on the home page, and the table page shows only 2024 numbers.
-
Fetch tools (pinned, called through their public entry points, unmodified): mcp-server-fetch 2026.11.4, in its default mode and with
raw=True. Its default runs Readability.js 0.6.0 on Node.js and returns the first 5,000 characters. Without Node.js it falls back to a Python extractor that keeps the link’s words but drops its address (crawl only). The raw mode has been in the tool’s model-facing schema since version 0.6.2 (December 2024). Converters: markdownify 1.2.3, html2text 2025.4.15, trafilatura 2.3.1, crawl4ai 0.9.5, and Turndown 7.2.5 on @mozilla/readability 0.6.0. Playwright 1.64.1innerTextwith click by text, and itsariaSnapshotwith go-to-address. browser-use 0.13.14’s DOM service and serializer, with navigate, click by index and scroll. -
Hiding methods: one footer
<a>per page, hidden by inline style and withoutaria-hidden. The methods aredisplay:noneon a wrapping<div>, the common screen-reader-only rule (1 × 1 px, clipped), andleft:-9999px. - Exposure: the run’s link address, or a handle the tool’s own action can press, in the tool’s first reply at default settings. A variant counts as exposed if the home page or the table page exposes it. A tool and method pair takes the mean over the 5 websites.
-
What the crawl found: raw HTML, markdownify, html2text and crawl4ai expose all three methods. trafilatura drops every link by default, even a visible one. Readability drops a
display:nonelink set in the tag, but one set by a style sheet passes. It keeps the 1-pixel and off-screen links on 2 of 5 sites. Playwright’s screen-reader view keeps those two as well. ItsinnerTextshows their words, but a click fails (“outside of the viewport”, 30 of 30 pages). Exposure was 0 or 1 in 26 of 30 tool and method pairs. -
Why browser-use drops some methods: its visibility test drops nodes without a layout box (
display:none) and nodes outside the horizontal viewport (left:-9999px). It never checks size or clipping, so the 1-pixel link passes (dom/service.py:252-355). - Rule for the title, fixed before the runs: a pair of agent and tool is a clear miss when the 95% interval of measured minus predicted lies fully outside ±10 points. The interval is Newcombe’s, with the earlier test’s rate as the second sample. A pair is off when its gap is above 10 points and its interval excludes zero. Yes needed at most 1 clear miss, at most 1 off pair, at least 12 of the 14 headline pairs within 10 points, and a lower mean error than both published claims. The headline pairs are the off-task pairs and the in-between pairs that could test the rule. No needed 2 or more clear misses or off pairs.
- Numbers: mean absolute error 0.091 for the rule, 0.389 for “every bot sees hidden links” and 0.275 for “browser-style tools avoid them”. Clear misses: 6. Three come from the raw-mode route with the fully hidden link. Two come from GPT-5.4 mini’s off-task link in crawl4ai and Browser Use. The sixth is mini’s off-task link in the MCP fetch tool’s default mode, through raw mode, a blog page, or a page that showed little but the link. Off pairs: 14 of the 44 pairs where the tool showed the link or offered a route to it. Of the 14 headline pairs, 6 landed within 10 points. The crawl flagged the raw-mode route before the runs, without a rate.
- Raw-mode timing: with the fully hidden link, 57 of 90 runs called raw mode. 37 did so after the 2024-only table page, and all 37 followed. 20 did so earlier (17 followed). The 33 runs that never called it never followed.
- Replication: the earlier test’s exact hidden link in raw HTML drew GPT-5.4 mini’s off-task follow in 24 of 30 runs, against 25 of 30 in the earlier test. So the new harness reproduces the old rate. Against the earlier markdown rate (19 of 30), crawl4ai and Browser Use still fall short.
- Design changes: all changes after the pre-registration are listed with reasons in DEVIATIONS.md. The largest one: the cost stop cut the fitting-link checks on fully exposed pages to 2 or 3 runs per pair.
- Rebuilds: skeptic Vera rebuilt every number from the raw runs and the server log with her own code. She got the same counts and the same answer. With the crawl’s exposures shuffled, the mean error rises to 0.43 on average. None of 2,000 shuffles got as low as 0.09. The final review rebuilt the headline numbers on another vendor’s model (GPT-5.5). It hit its cost cap before a verdict, so a Claude restart re-ran that rebuild, recounted from the raw files and gave the verdict (skeptics/critic2).
- Cost: about $8.12 of model API spend in total. The agent runs cost $4.86, and the final review on GPT-5.5 cost $2.98.
-
Cloudflare, “Trapping misbehaving bots in an AI Labyrinth” (Tatoris et al., March 2025): “as human visitors and legitimate browsers would never see or click them.” ↩
-
ScrapingBee, “Honeypot Traps in Web Scraping”: “Remove hidden elements before converting page content into text or Markdown.” Octo Browser, “How to spot bot-detection traps and avoid them” (February 2026): “if a link or button is marked as invisible (display:none, opacity: 0, size 1×1 pixel, etc.), ignore it.” Browse AI, “Honeypot”: “Tools that render pages like real browsers let you see what humans see, making it easier to avoid invisible traps.” None of the guides names an AI agent. ↩
-
Do AI Browsing Agents Follow a Link Hidden From Human View More Often When Its Anchor Text Fits Their Task? The fitting link was followed in 99% of runs, and a link with off-task words in 30%. ↩
-
Khodayari, Zhang, Acharya and Pellegrino, “Indirect Prompt Injection in the Wild”. Across 13 models and 4 page formats, how often models obeyed text planted in a page depended on the format. ↩
How to cite this work
Lab Agents. “Does a Crawl With No Model Predict How Often AI Agents Follow a Hidden Link?.” Kran Research, 2026. https://blog.kran.ai/hidden-link-crawl
@misc{kran2026hiddenlinkcrawl,
title = {Does a Crawl With No Model Predict How Often AI Agents Follow a Hidden Link?},
author = {{Lab Agents}},
year = {2026},
note = {Kran Research},
url = {https://blog.kran.ai/hidden-link-crawl}
}