You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Every page advertises llms.txt and llms-full.txt, but they are only generated for projects with an API reference — docs-only sites ship two dead links #350
The AI / Agents margin section appends links to llms.txt and llms-full.txtunconditionally. _generate_llms_txt and _generate_llms_full_txt both return early when _quarto.yml has no api-reference key.
For any project without an API reference — a pure documentation site — the files are never written and the links 404.
Root cause
core.py, building the margin section. The Skills item is gated; the two below it are not:
The generator is called unconditionally during the build and the step is logged as Created llms.txt + llms-full.txt, so the build reports success while having written nothing.
Minimal repro
Any great-docs.yml with sections: and no api-reference in the generated _quarto.yml. Build, then:
Confirmed on our own site: index.html and skills.html each carry both links, and no llms*.txt exists anywhere in the project or the built output.
Impact
Two dead links on the front page of every documentation-only site, in a section specifically aimed at agents — which are the readers least likely to report a 404 and most likely to be confused by one.
It is also quietly misleading: the build log says the files were created.
Suggested fix
Gate the links on the same condition the generators use — or, better, have the generators produce a section index for non-API projects rather than returning. The sections: structure already carries titles and page lists, which is most of what llms.txt wants.
If gating is the preferred route, the minimal version is to have _generate_llms_txt report whether it wrote anything and append the links only when it did, so the two cannot drift apart again.
Workaround
We generated the two files ourselves for several days, then deleted that and now strip the two links from the built HTML instead — our site is not published, so an index for crawlers had no reader either way.
Version
great-docs 0.17.0 (latest on PyPI at time of writing), Python 3.13, Windows.
Hi, thanks for the clear report. I picked this up and opened #410.
The root cause turned out to be one step past #351. That PR gated the places
that advertise the files on _llms_txt_available(), but the code deciding
whether the files are actually written still had three separate opinions about
when to run:
_generate_llms_full_txt() only required an api-reference block with a package, so an empty sections list still produced a header-only llms-full.txt.
_prepare_for_freeze() called both generators directly, bypassing the
predicate build() gates on, so the freeze path could leave files behind
that a full build never writes.
The fix introduces _llms_txt_quarto_config() as the single source of truth for
the structural half of the guard, has the predicate and both generators share
it, and makes _prepare_for_freeze() honour the same predicate as build().
Tests are parametrized over six _quarto.yml shapes and assert the generators
and the freeze path agree with the predicate in every case.
Disclosure: this change was produced with the help of an AI coding agent, which
used Alpha as its tool.
Everything in the PR was reviewed by me and verified against the test suite.
Activity
Link llms.txt and llms-full.txt only when they are generated (#350)
tyza66 commentedon Oct 22, 2026
Hi, thanks for the clear report. I picked this up and opened #410.
The root cause turned out to be one step past #351. That PR gated the places
that advertise the files on
_llms_txt_available(), but the code decidingwhether the files are actually written still had three separate opinions about
when to run:
_generate_llms_full_txt()only required anapi-referenceblock with apackage, so an emptysectionslist still produced a header-onlyllms-full.txt._prepare_for_freeze()called both generators directly, bypassing thepredicate
build()gates on, so the freeze path could leave files behindthat a full build never writes.
The fix introduces
_llms_txt_quarto_config()as the single source of truth forthe structural half of the guard, has the predicate and both generators share
it, and makes
_prepare_for_freeze()honour the same predicate asbuild().Tests are parametrized over six
_quarto.ymlshapes and assert the generatorsand the freeze path agree with the predicate in every case.
Disclosure: this change was produced with the help of an AI coding agent, which
used Alpha as its tool.
Everything in the PR was reviewed by me and verified against the test suite.
fix: keep llms.txt generation behind one shared guard