Or, how one simple question unexpectedly turned into a micro-investigation.
You can discover a new dev tool in all sorts of ways — a friend's recommendation, a sponsored ad, take your pick. Once the pitch has you sold, naturally you'll want to kick the tires before working it into your workflow. That's where the surprises start.
Skipping the boring backstory — this morning I ended up on the Context7 website — an MCP server promising always up-to-date documentation for a huge number of frameworks, languages, and libraries.
Impressive and inspiring. Typing "wordpress" into the search field gave a pretty reasonable-looking set of results. Note the third line, where we see, in fact, the official WordPress repository (or rather, the mirror of its subversion repo).
My hands were already reaching for the keyboard to install it, when a modest little "Try live" link in the menu caught my eye. Well, why not? Let's open the chat and ask the simplest question: "Latest known WordPress release."
The AI consistently reviewed several documentation packages (and /wordpress/wordpress was not among them) and... reported that the latest version it knew of was WordPress 6.7 "Rollins," released in November 2024. Hey, what happened to "up-to-date" and "version-specific"?! To be fair, the chat does helpfully explain how to check the version yourself — but that's not really the point, is it?
Fair enough, maybe that question was just badly phrased. Let's try to be more specific. Let's ask about the main differences between 6.9 and 7.0 — there was one small but important change in there, and I needed the details for a project. Let's ask.
Looks like this one's going unanswered too. You'd think this is exactly the kind of question "version-specific" docs exist to answer. Now I was curious, so let's dig further.
Fair play to the AI here — it was a trick question, there's no such standalone function in WordPress, only a class method. No false positive this time. Let's ask directly about the filter we're interested in.
Good, we got information about the filter. The one thing that stood out as odd: the filter's availability is listed as starting from version 5.6. However, let's come back to that a bit later — first it would be good to clarify information about the method where this filter is used. This is where things get really interesting; here is the specific code shown in the response:
public function get_page_cache_headers(): array {
$cache_hit_callback = static function ( $header_value ) {
return 1 === preg_match( '/(^| |,)HIT(,| |$)/i', $header_value );
};
$cache_headers = array(
// Standard HTTP caching headers.
'cache-control' => static function ( $header_value ) {
return (bool) preg_match( '/max-age=[1-9]/', $header_value );
},
'expires' => static function ( $header_value ) {
return strtotime( $header_value ) > time();
},
'age' => static function ( $header_value ) {
return is_numeric( $header_value ) && $header_value > 0;
},
'last-modified' => null,
'etag' => null,
'via' => null,
// Vendor/custom headers (ported from AMP plugin → Performance Lab → core).
'x-cache-enabled' => static function ( $header_value ) {
return ( 'true' === strtolower( $header_value ) );
},
'x-cache-disabled' => static function ( $header_value ) {
return ( 'on' !== strtolower( $header_value ) );
},
// Cloudflare.
'cf-cache-status' => $cache_hit_callback,
// Fastly.
'x-cache' => $cache_hit_callback,
// LiteSpeed.
'x-litespeed-cache' => $cache_hit_callback,
);
return $cache_headers;
}
At first glance, it looks credible. But only at first glance. Let's return to the main question — about the differences between versions 6.9 and 7.0 — and recall the claimed availability of the filter since version 5.6. Head over to the GitHub releases for that repo and diff two tags: 6.9.7 and 7.0.4. We're interested in the commit that touches the get_page_cache_headers method. Here's the method in full, docblock included, for clarity:
/**
* Returns a list of headers and its verification callback to verify if page cache is enabled or not.
*
* Note: key is header name and value could be callable function to verify header value.
* Empty value mean existence of header detect page cache is enabled.
*
* @since 6.1.0
*
* @return array List of client caching headers and their (optional) verification callbacks.
*/
public function get_page_cache_headers() {
$cache_hit_callback = static function ( $header_value ) {
return str_contains( strtolower( $header_value ), 'hit' );
};
$cache_headers = array(
'cache-control' => static function ( $header_value ) {
return (bool) preg_match( '/max-age=[1-9]/', $header_value );
},
'expires' => static function ( $header_value ) {
return strtotime( $header_value ) > time();
},
'age' => static function ( $header_value ) {
return is_numeric( $header_value ) && $header_value > 0;
},
'last-modified' => '',
'etag' => '',
'x-cache-enabled' => static function ( $header_value ) {
return 'true' === strtolower( $header_value );
},
'x-cache-disabled' => static function ( $header_value ) {
return ( 'on' !== strtolower( $header_value ) );
},
'x-srcache-store-status' => $cache_hit_callback,
'x-srcache-fetch-status' => $cache_hit_callback,
// Generic caching proxies (Nginx, Varnish, etc.)
'x-cache' => $cache_hit_callback,
'x-cache-status' => $cache_hit_callback,
'x-litespeed-cache' => $cache_hit_callback,
'x-proxy-cache' => $cache_hit_callback,
'via' => '',
// Cloudflare
'cf-cache-status' => $cache_hit_callback,
);
/**
* Filters the list of cache headers supported by core.
*
* @since 6.1.0
*
* @param array $cache_headers Array of supported cache headers.
*/
return apply_filters( 'site_status_page_cache_supported_cache_headers', $cache_headers );
}
Notice anything odd? The @since annotations indicate that both the filter and the function have been available since version 6.1.0, not 5.6 at all. Also, $cache_hit_callback is defined far more simply than what Context7 showed, and the $cache_headers array differs both in how it's grouped and in what it actually contains. Let's download the archive of the 5.6.19 release!
A search through the 5.6.19 release files turns up neither the get_page_cache_headers method nor the site_status_page_cache_supported_cache_headers filter anywhere in the code. Over in the repo, I pulled up wp-admin/includes/class-wp-health.php and checked its edit history. There's the commit that added get_page_cache_headers — and confirms there's no preg_match( '/(^| |,)HIT(,| |$)/i', $header_value ) anywhere in it. A bit later, another commit swaps false !== strpos( ... ) for str_contains(), and after that, this block doesn't change again. Doing the same digging elsewhere confirms that the way the headers array is written in any version of the real file differs from what was shown in the Context7 chat. On top of that, the AI has no idea the array even contains headers like x-srcache-store-status, x-srcache-fetch-status, and x-proxy-cache, and instead of the x-cache-status header it suggests using x-cache-enabled and x-cache-disabled.
You could argue this is a pretty niche, rarely-used bit of the codebase. But people build more than just themes for WordPress — plugins too, including ones that extend core functionality. And caching plugins are hardly a niche category.
I'm not here to argue Context7 is useless — I don't have nearly enough AI experience to make that call. But I hope this piece at least flags some potential blind spots — for WordPress developers, anyway.






Top comments (0)