## TL;DR
Deduplicate heading anchors the way renderers do: append a counter to repeats. The agent emitted the same anchor for every identical heading, so only the first one was linkable and every duplicate link jumped to the wrong place.
Fix: slug each heading, track used slugs per page, and suffix repeats with -1, -2, matching the renderer's convention.

## The error
```text
docs agent failed: produced duplicate anchors in markdown headings
```

## Steps
1. Find the duplicate: search the generated page for two headings with the same text and check their anchors in the HTML output.
   Expected: two elements share one anchor id, or the second has no id at all.
2. Check how the agent builds anchors: if it slugs the heading text with no dedup tracking, that is the bug.
   Expected: you confirm slugs are generated without a used-set.
3. Add per-page dedup: keep a count of each slug; the first use keeps the bare slug, repeats get -1, -2, and so on, matching the GitHub and common markdown renderer convention.
   Expected: every heading on the page has a unique anchor.
4. Update the table of contents and all in-page links to use the suffixed anchors for the repeated headings.
   Expected: each TOC entry scrolls to its own section.
5. Add a build-time check that fails on duplicate anchor ids per page.
   Expected: future duplicates are caught before publishing.

## Use this when
- TOC links jump to the wrong section on pages with repeated headings
- two headings on one page share the same anchor
- the agent generates its own anchors instead of letting the renderer do it

## Not for this skill when
- anchors are unique but links are broken (a link-target issue)
- the renderer handles anchors and the agent should not generate them at all (then delete the custom anchor code)
- headings differ but slug to the same anchor (a slug-collision edge; the same dedup fix applies)

## Variant phrasings
- duplicate heading ids in generated markdown
- toc links to wrong section with same heading text
- anchor collision in docs agent output
- repeated headings share one anchor link

## Why it happens
Slug generation is a pure function of heading text, so identical headings deterministically produce identical anchors. Renderers solve this with a per-page counter, but the agent's custom anchor code skipped that step, assuming headings were unique.

## Edge cases
- Case-only differences in headings: slug both to lowercase first, then dedup, since most renderers treat them as the same anchor.
- Headings that differ only by punctuation: these also collide after slugging; the counter handles them.
- Explicit custom anchors in source: respect them and still dedup against generated ones.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_iv9FhNyJmfUN_MAN4D4anQ
