---
name: developer_troubleshooting_docs
description: "Turn support tickets and error records into troubleshooting pages developers find by pasting the exact error string: group tickets by root cause, write the page around the verbatim error text, wire the error code list back into product output, and retire pages when the cause is fixed. Use when a team has repeating tickets, a pile of error codes with no docs, or troubleshooting pages nobody can find. Ships a ticket to page worksheet, a clustering script, a worked page built from a ticket cluster, and a review cadence tied to releases."
---

# Developer Troubleshooting Docs

## Purpose

Most repeating tickets already contain a troubleshooting page, scattered across replies. One ticket holds the exact error text, another holds the real cause, a third holds the fix that worked. This skill pulls those parts together into one page per root cause, titled and indexed so a developer who pastes the error string into search lands on it.

The method follows three established practices. Knowledge-Centered Service says to capture knowledge while solving the ticket, not in a separate project later. Microsoft Learn troubleshooting articles use Symptoms, Cause, and Resolution as the core shape. MDN error pages require the message exactly as thrown, why it happened, an example that triggers it, and an example that fixes it.

## Workflow

### 1. Export and clean the ticket pile

- Pull the last full release cycle of tickets, plus any open tickets with an error string. Keep these fields per ticket: id, exact error text, title, product version, status, and the resolution reply that closed it.
- Strip names, emails, account ids, tokens, and customer data from error text before anything leaves the support system. Keep the error structure intact. A redacted page that changed the wording helps nobody search.
- Keep one row per ticket. Do not summarize errors at this stage. Summaries destroy the exact strings the page will be built around.

### 2. Group tickets by root cause, not by wording alone

- Run the clustering script for a first pass:

  `python3 scripts/cluster_tickets.py tickets.csv --min-size 2 --out clusters.md`

- Read the script output as a draft, not a verdict. The script normalizes numbers, quoted values, paths, timestamps, and ids, then groups tickets with the same normalized error. It is conservative by design. Two quota errors from different regions land in separate clusters even when the cause is the same.
- Merge or split clusters by hand using the resolution replies. The grouping question is: did the same fix close these tickets? If yes, they share a page. If one fix worked and another was needed, they are two causes with similar symptoms and they get two pages, cross linked.
- Name each surviving cluster with a short root cause tag in plain words, for example `expired_token_no_refresh`, not a ticket id and not a team name.
- Fill in one row of the worksheet in `references/ticket-to-page-worksheet.md` per cluster. A cluster with no confirmed fix does not become a page yet. It goes back to support and engineering with the ticket ids attached.

Starting rule, tune it to your volume: a cluster needs at least three tickets in a release cycle, or one ticket from a paying account blocked with no workaround, before it earns a page. Single odd tickets stay as ticket replies.

### 3. Decide page, fix, or both

- Sort each cluster into one of three outcomes and record it on the worksheet:
  - Page only: the cause is user side or environment side, the fix is in the reader hands, and the product behaves as designed. Example: a token expired because the clock is wrong.
  - Product fix only: the cause is a bug, a release fixes it, and after the fix the error cannot occur. No page. File the bug with the cluster ticket ids as evidence.
  - Page plus product fix: the bug is real but users on older versions will hit the error for months. Write the page, name the fixed version in it, and set its retirement check for the release after the fix ships.
- Never write a page as a substitute for fixing a clear bug. The worksheet forces the choice in writing so the page pile cannot quietly absorb product defects.

### 4. Write the page around the exact error text

- Use the template in `assets/troubleshooting-page-template.md`. Copy the structure from the worked example in `references/worked-example.md` when the shape is unclear.
- Put the exact error string, word for word, in three places: the page title or subtitle, a code block under Symptoms, and the first paragraph. Search engines and site search match pasted text. A page titled only with a paraphrase will not be found by paste.
- Keep one root cause per page. If the same error has two causes, write the page with a short check that tells the reader which branch they are on, then give each branch its own resolution. Do not merge unrelated causes to keep the page count low.
- Write Symptoms from the reader side: what they ran, what they saw, what stopped working. Include version, platform, or plan limits only where they change the diagnosis.
- Write Cause in plain language, in two to five sentences. Name the invalid value, the missing permission, or the limit that was hit, with the actual numbers from a real ticket where the page can do so safely. This follows the Google error message guidance: identify the cause, specify the value that failed, and state the constraint.
- Write Resolution as numbered steps, one action per step, in the order a reader does them. End the resolution with a check step that proves the fix worked, for example the command to rerun and the output to expect. A resolution with no check step leaves the reader guessing.
- Add a short What to send support section for the case where the steps fail: the error text, the version, the steps already tried, and any request id or instance id the product prints. This turns the next ticket into a short one.
- Use sentence case headings and task based titles, per the Google developer documentation style guide. Keep explanation short and link out to concept or reference pages instead of mixing them in. A troubleshooting page is a how-to guide in the Diataxis sense: it serves a competent reader at work, and its job is the fix.

### 5. Wire the error list back into the product

- Build one error registry, owned in the codebase or the docs repo, with one row per error the product can emit: error code or type string, exact message text, page URL, fixed in version if any, and owner.
- For HTTP APIs, prefer the RFC 9457 problem details shape where you control the API: `type` as a URI that identifies the problem type, `title` that stays the same across occurrences, `detail` that explains this occurrence and helps the client correct it, and `status` and `instance` where they help. When the `type` URI points at the troubleshooting page, dereferencing it gives the reader the documentation for that problem type, which is the behavior RFC 9457 describes for locator type URIs.
- For CLIs and apps, add the same link in the error output itself: error text, one line with the fix in short form, then the page URL. Google guidance for long errors is to link to expanded documentation instead of printing the full explanation in the message.
- Add a test or a lint check to the release process: every new error string added in a pull request must either add a registry row or state why it needs none, for example an internal error that users never see. An error with no registry row is a page that will never exist and a ticket that will repeat.
- When a message text changes, update the registry and the page in the same change. Keep the old exact string on the page under a line such as "In versions before 2.4.0 this appeared as:" so old pasted searches still land.

### 6. Publish where paste search works

- Publish on a site that search engines can index and that your own docs search indexes by full text, not title only. Confirm both before counting the page as done.
- Test the page the way a stuck developer finds it: paste the exact error string, in quotes and without quotes, into a search engine and into your docs search. The page should appear in the first results in both. If it does not, fix the title, the first paragraph, or the indexing before writing more pages.
- Link the page from the related how-to, the API reference entry for the call that fails, and the release notes for any version that changes the cause.
- In support replies, send the page link instead of retyping the fix, and attach the page to the ticket. In KCS terms this is the reuse step, and the attachment count is how you later prove the page is working.

### 7. Review on the release cadence and retire on purpose

- Run the cadence in `references/review-and-retirement.md`. In short: a light check at every release, a cluster rerun every quarter, and a retirement check whenever a fix version reaches the oldest supported version.
- Retire a page only when all three are true: the cause is fixed, the fixed version is the oldest version you still support, and tickets for the cluster have stayed at zero for a full release cycle. Retiring means redirecting the page URL to the relevant release note or reference page, not deleting it. Pasted searches from old logs and old tickets still arrive.
- If tickets return after retirement, reopen the page from the redirect, note the version where the problem came back, and treat it as a new cluster.

## Output Contract

A finished run delivers:

- A clusters file from `scripts/cluster_tickets.py`, hand corrected, with one root cause tag per cluster and a page, product fix, or page plus fix decision per cluster.
- A completed worksheet in `references/ticket-to-page-worksheet.md` for every cluster that became a page.
- One troubleshooting page per approved cluster, built from `assets/troubleshooting-page-template.md`, with the exact error string in the title area, Symptoms, and first paragraph, a named cause, numbered resolution steps, a check step, and a what to send support section.
- An updated error registry with a row for each error on each new page, and a product side link from the error output to the page where that wiring was in scope.
- A search test record: the exact strings tested, where they were tested, and the result rank or a note of what was fixed to improve it.
- A review entry with the next review release named, and a retirement condition written for every page whose cause has a fix version.

## Operating Rules

- One page per root cause. Similar wording is not a shared cause, and a shared cause with different wording still shares a page.
- Exact strings only. Never paraphrase the error in the title, the Symptoms block, or the registry. Paraphrase belongs in the Cause section, after the verbatim text.
- No page without a confirmed fix. Guessed resolutions become wrong pages that support then has to un-teach. If the fix is not confirmed, the output is a bug report or an investigation note, not a page.
- No invented facts. Versions, limits, and error texts come from tickets, code, or product output in front of you. If a limit or a version cannot be verified, leave it out or mark it as needing confirmation on the worksheet.
- Keep customer data out. Redact before clustering, and check the finished page for account details, tokens, file paths from a customer machine, and names.
- Pages are support tools and product feedback at the same time. Every cluster report goes to the product owner of that area, not only to the docs backlog.
- Retire by redirect, never by deletion. Old error text lives in logs, tickets, and forum posts long after the fix ships.
