llms.txt Shows Wrong URLs or Strange Characters? Here’s the Fix
A field guide to the issues most likely to come up with Waggle’s llms.txt and machine files — what causes each, how to confirm it, and how to fix it.
llms.txt shows the wrong domain (e.g. staging URLs)
Symptom. Your llms.txt lists URLs for a different host than your live site — most often a staging domain like stage.example.com — even though the rest of the site (canonical tags, sitemap) uses the correct domain. Clicking Force rebuild in Waggle doesn’t change it.
Why this happens. Waggle serves /llms.txt dynamically: every URL in it is built live from WordPress’s own home_url() at render time. So if your sitemap and canonical tags are correct, Waggle is generating the right URLs. When /llms.txt still shows the wrong domain, something is being served in front of Waggle, and WordPress never runs for that request. Two things cause this:
- A physical
llms.txtfile in your web root. On most hosts (nginx, and Apache with static-file precedence) the web server serves an existing file straight from disk before PHP/WordPress ever loads. If a file was created there once — by an export tool, an old plugin, or a migration — it “shadows” Waggle’s dynamic version permanently. This is the usual culprit when Force rebuild has no effect and a cache-busting query string (/llms.txt?x=123) still returns the old file. - An edge or page cache (Cloudflare, or a host cache like SpinupWP/Nginx FastCGI) holding an old copy of the response — often one generated while the site was still on its staging domain.
How to confirm which one — read the response headers. This is the fastest and most reliable test. From a terminal:
curl -sI https://example.com/llms.txt
Compare against how Waggle serves the file. When Waggle renders /llms.txt it sends Content-Type: text/plain; charset=UTF-8 and, being dynamic PHP, sends no Last-Modified or ETag. So:
Content-Type: text/plainwith nocharset, plus aLast-Modifieddate and anETag→ it’s a static file on disk (cause #1). The web server (nginx) is serving a real file and Waggle never runs. TheLast-Modifieddate tells you when that file was created — often the giveaway that it predates your migration. Nginx’sETageven encodes the file:W/"<mtime-hex>-<size-hex>".cf-cache-status: HIT, or a host cache header likex-cache: HIT→ it’s an edge/page cache (cause #2). Notecf-cache-status: DYNAMICmeans Cloudflare is not caching it and is passing straight to origin — so if you also see the staticLast-Modified/ETagabove, the problem is the file on disk, and clearing Cloudflare or the host cache will do nothing.
Worked example (a real diagnosis): the response came back content-type: text/plain (no charset), last-modified: Mon, 16 Mar 2026 21:12:04 GMT, etag: W/"69b87224-d59", cf-cache-status: DYNAMIC. That’s unambiguous — a 3417-byte static file (0xd59 = 3417) last written on March 16, served by nginx, with Cloudflare passing through. Force rebuild and every cache purge were no-ops because none of them touch a file on disk.
Fix.
- Static file: remove the physical file from your web root over SSH/SFTP — the WP admin can’t do this. On a SpinupWP + DigitalOcean host the web root is typically
~/<site-name>/files(confirm the exact path in SpinupWP → your site → Web Root):cd ~/example.com/files # your actual web root ls -la llms.txt # confirm it's there mv llms.txt llms.txt.bak # rename (safer than delete — keeps a backup) curl -sI https://example.com/llms.txtSuccess looks like the response flipping to
content-type: text/plain; charset=UTF-8with nolast-modified/etag— that’s Waggle serving it live, with correct URLs. While you’re there, check for the same shadow on siblings:ls -la robots.txt sitemap.xml. - Edge/page cache: purge the
/llms.txtURL from your host’s cache, and from Cloudflare if it’s in front of your site.
The deeper cause on migrations. If your site was recently moved from a staging domain, the fix above resolves the served file. If URLs are still wrong after clearing any shadowing file/cache, confirm WordPress itself has the right address at Settings → General → WordPress Address / Site Address, and that a migration search-replace updated home/siteurl in the database.
llms.txt (or .md) looks garbled — — instead of —
Symptom. Dashes and apostrophes show as â€", ’, é, etc. — for example Diviâ€"make instead of Divi—make.
Almost always a viewer problem, not a file problem. Waggle serves these files as UTF-8 (Content-Type: text/plain; charset=UTF-8). The â€" pattern is the classic signature of a UTF-8 file being decoded as Windows-1252 by whatever opened it — a terminal, a text editor, or a copy-paste into an app with the wrong encoding. The bytes on the server are correct.
How to verify the file is fine.
curl -s https://example.com/llms.txt | grep -m1 —
If that finds a real em-dash, the file is correct UTF-8 and the garbling is in your viewer. Open it in a UTF-8-aware tool (or view it in a browser) and it will read correctly.
When it is real. If the garbling appears in a browser too — and on your normal site pages, not just llms.txt — then the source content in the database is double-encoded, usually from a migration where a UTF-8 dump was imported over a latin1 connection. That’s a site-wide data issue to fix at the database level (a proper UTF-8 re-import or a targeted search-replace), independent of Waggle.