---
title: 'Troubleshooting Content'
source: 'https://academia.sh/en/courses/technical-writing/troubleshooting-content'
course: 'Technical Writing and Documentation'
language: en
updated: '2026-08-17T18:10:49+00:00'
license: 'CC BY-SA 4.0'
---

# Troubleshooting Content

A reader arriving with a symptom reaches only 8 of a concept-first text's 17 defects and meets 8 of 51 decisions (0.1569); a symptom-cause-remedy layout reaches all 17 at once and meets 51, but the 39 silently stale claims produce no symptom at all and stay outside troubleshooting too.

The previous lesson closed one of the reader's two unanswered questions: release notes
made a stale claim's fall version datable. The second remains, and it is asked far more
often than the first: **"why is this not working?"**

The reader arriving with this question has no subject name in hand. No version number
either. All they have is a **symptom** the product showed them: an error line, an
empty output, a result other than expected. This lesson measures how much of this a
symptom-first text covers, and how much a concept-first text covers.

## The Reader Who Arrives With a Symptom

The four types and release notes shared one assumption: the reader can **name** what
they are looking for. Whoever comes to a tutorial says "I want to start"; whoever comes
to a reference says "this field's type"; whoever comes to release notes says "what
happened at version six." All five texts are indexed by a name.

A reader arriving with a defect cannot do this. What they see is not a name, it is a
**result** — and if they knew which concept that result belonged to, they would already
have solved it. The mismatch sits exactly here: **the document's index is concept, the
reader's index is symptom.** The reader is expected to translate between the two
indexes, and they are there precisely because they cannot make that translation.

Troubleshooting content is the text that translates the index. It is a separate type
not because it carries different information — most of what it carries already sits in
the explanation and the reference — but because it is **indexed differently**: its
entries start from the symptom.

## Symptom, Cause, Remedy

A troubleshooting entry has three sections, and the three meet three separate reader
needs.

```text
# an entry from the invented product's troubleshooting section
# example text, not executed

symptom  The `station start` command exits printing:
         "unknown option: --interval"

cause    The sampling interval is no longer given by the call option
         but by a profile field; the old option was removed.

remedy   Write the interval into the `sampling` field of the profile
         file and run the command without the option.
```

**Symptom** meets the reader's **recognition** need: is what they are seeing a known
defect, or an oddity in their own setup? This answer matters more than it might seem;
what eats the reader's hours is often not the defect itself but not knowing whether the
defect is recognized. **Cause** meets the reader's **cause** need. **Remedy** meets
the reader's **action** need.

The symptom section is the hardest of the three to write, because it has to be written
**in the exact form the reader sees it.** "The interval option was removed" is not a
symptom, it is a cause; the reader does not type that into a search box. What the
reader types is the line they see on screen. This is the point troubleshooting content
misses most often: an entry headlines the correct information under a name the reader
will never search for, and it is never found.

## The Cost of Starting From Concept

The same information also has a concept-first version, and it is usually already
written: the explanation text describes what the sampling interval is and where it
comes from. If the reader could reach that text, they would have solved the defect.

Reaching it depends on one condition: **the defect itself has to name what changed.**
The line "unknown option: --interval" does name it — the reader takes the string
`--interval`, searches the document, and lands on the explanation. But not every defect
speaks this way. When the order of steps changes, what comes out is not a name, it is
an **absence**: the command runs, throws no error, and produces something other than
the expected result. The reader has no string in hand to search for, and cannot enter
the concept index at all.

The measurement counts this distinction. Defects bound to the signature and name
surfaces name themselves; ones bound to the flow surface do not.

The measurement's assumptions:

- **DT47** — The measured set is the course's shared setup: **56** claims, four types,
  four surfaces, **17** embedded examples. The mix and surface frequencies are not
  changed.
- **DT48** — The measurement is done **at version twelve**, where every claim is stale
  and the widest set troubleshooting content could possibly reach exists.
- **DT49** — A **symptom** arises only once a claim embedded in a runnable example
  goes stale. When a claim that is not embedded goes false, the product shows nothing.
- **DT50** — Every symptom corresponds to exactly one troubleshooting entry; two claims
  producing the same symptom does not occur in this measurement.
- **DT51** — The reader has three needs in the face of a defect: **recognition**,
  **cause**, **action**. These are separate from the course's six reader questions and
  sit inside a single defect.
- **DT52** — **Concept-first** text is indexed by concept; the reader reaches an entry
  only if the defect **names** what changed.
- **DT53** — Defects bound to the **signature** and **name** surfaces name themselves
  (a missing field, an unknown option, an error code not found); ones bound to
  **flow** do not.
- **DT54** — **Symptom-first** text is indexed by symptom; because the reader already
  holds the symptom, they reach every entry.
- **DT55** — A reached entry closes only the needs met by **the sections it carries**;
  a section it does not carry sends the reader to another text and is counted as unmet
  in this measurement.
- **DT56** — Concept-first text carries only the **cause** section; giving action is
  not explanation's job, and this is taken as the type's definition, not a defect.
- **DT57** — The decision scale is **symptom count × need count**; every need of every
  symptom is a separate decision.
- **DT58** — The set's resolution is **1/56** at the claim scale, **1/51** at the
  decision scale.

## Measurement

```python
"""Troubleshooting content: symptom-first text versus concept-first text.

Part 1 - how many stale claims produce a symptom, how many produce none.
Part 2 - the symptoms and reader needs three text layouts reach.
"""
TYPES = {
    "tutorial":      {"flow": 9, "signature": 3, "name": 2, "concept": 1},
    "how-to":        {"flow": 6, "signature": 5, "name": 2, "concept": 1},
    "explanation":   {"flow": 1, "signature": 1, "name": 1, "concept": 9},
    "reference":     {"flow": 0, "signature": 13, "name": 2, "concept": 0},
}
FREQUENCY = {"signature": 2, "flow": 3, "name": 5, "concept": 12}
EMBEDDED = {"tutorial": 0.60, "how-to": 0.70, "explanation": 0.10,
            "reference": 0.00}
VERSION = 12
# Does the defect itself name what changed: this is how the reader finds the concept.
SELF_NAMING = {"signature", "name"}
# The reader's three needs when facing a defect.
NEEDS = ("recognition", "cause", "action")
# Text layout -> (index, needs met by the sections it carries).
LAYOUTS = {
    "concept-first": ("concept", ("cause",)),
    "symptom-first (symptom-remedy)": ("symptom", ("recognition", "action")),
    "symptom-first (symptom-cause-remedy)":
        ("symptom", ("recognition", "cause", "action")),
}


def claims():
    entries, no = [], 0
    for kind, mix in TYPES.items():
        embedded_target = 0
        for surface, count in mix.items():
            for _ in range(count):
                no += 1
                embedded_target += EMBEDDED[kind]
                embedded = embedded_target >= 1 and surface != "concept"
                if embedded:
                    embedded_target -= 1
                entries.append({"no": no, "type": kind, "surface": surface,
                                 "embedded": embedded})
    return entries


L = claims()
stale = [i for i in L if VERSION // FREQUENCY[i["surface"]] >= 1]
# A symptom arises only when a claim embedded in a runnable example goes stale.
symptomatic = [i for i in stale if i["embedded"]]
silent = [i for i in stale if not i["embedded"]]
print(f"version {VERSION} | claims {len(L)} | stale {len(stale)} | "
      f"produces symptom {len(symptomatic)} | produces no symptom {len(silent)}")
print()
print(f"{'surface':<9s} {'stale':>5s} {'symptom':>7s} {'no symptom':>10s} "
      f"{'defect names itself':>20s}")
for y in FREQUENCY:
    g = [i for i in stale if i["surface"] == y]
    b = [i for i in g if i["embedded"]]
    print(f"{y:<9s} {len(g):5d} {len(b):7d} {len(g) - len(b):10d} "
          f"{('yes' if y in SELF_NAMING else 'no'):>20s}")

print()
total = len(symptomatic) * len(NEEDS)
print(f"symptoms {len(symptomatic)} | needs {len(NEEDS)} | "
      f"decisions {total}")
print()
print(f"{'text layout':<40s} {'reached':>8s} {'met':>10s} "
      f"{'ratio':>6s}")
for ad, (index, sections) in LAYOUTS.items():
    reached = [i for i in symptomatic
               if index == "symptom" or i["surface"] in SELF_NAMING]
    met = len(reached) * len(sections)
    print(f"{ad:<40s} {len(reached):8d} {met:10d} "
          f"{met / total:6.4f}")

print()
# Six reader questions: how many land on a text once two more types are added.
QUESTIONS = {
    "where do I start": "tutorial",
    "how do I do this": "how-to",
    "why is this the way it is": "explanation",
    "what type is this field": "reference",
    "what version did this change in": "release notes",
    "why is this not working": "troubleshooting",
}
print("reader question -> answering text")
for q, t in QUESTIONS.items():
    print(f"  {q:<30s} {t}")
print(f"questions {len(QUESTIONS)} | answered "
      f"{sum(1 for t in QUESTIONS.values() if t)} | unanswered "
      f"{sum(1 for t in QUESTIONS.values() if not t)}")
print(f"claims troubleshooting can cover {len(symptomatic)}/{len(L)} "
      f"({len(symptomatic) / len(L):.4f}) | stale claims it cannot reach "
      f"{len(silent)}")
```

```
version 12 | claims 56 | stale 56 | produces symptom 17 | produces no symptom 39

surface   stale symptom no symptom  defect names itself
signature    22       5         17                  yes
flow         16       9          7                   no
name          7       3          4                  yes
concept      11       0         11                   no

symptoms 17 | needs 3 | decisions 51

text layout                               reached        met  ratio
concept-first                                   8          8 0.1569
symptom-first (symptom-remedy)                 17         34 0.6667
symptom-first (symptom-cause-remedy)           17         51 1.0000

reader question -> answering text
  where do I start               tutorial
  how do I do this               how-to
  why is this the way it is      explanation
  what type is this field        reference
  what version did this change in release notes
  why is this not working        troubleshooting
questions 6 | answered 6 | unanswered 0
claims troubleshooting can cover 17/56 (0.3036) | stale claims it cannot reach 39
```

## Reading the Coverage

The middle table gives the lesson's main comparison. Seventeen defects and three needs
make **51** decisions.

**Concept-first** text reaches only **8** of the seventeen defects and meets **8**
decisions: ratio **0.1569**. Two separate losses stack on top of each other. The first
is reachability: nine defects bound to the flow surface do not name themselves, the
reader has no string to search for, and those nine entries are never found at all. The
second is coverage: even in the eight entries that are reached, only the **cause**
section exists; the reader learns the reason, not what to do.

**Symptom-remedy** layout reaches all seventeen at once and meets **34** decisions:
**0.6667**. The jump comes from a single change — the index changed. The content is the
same; only the entries' heading changed. This is the cheapest gain measured anywhere in
this course: without writing a single new sentence, the number of decisions met climbs
to more than four times its previous value.

**Symptom-cause-remedy** layout closes the set with **51/51**: **1.0000**. The
difference is **17** decisions, and all of it comes from the **cause** section. A
troubleshooting text with no cause section works, but it does not teach the reader:
the same reader comes back on a similar defect, because they never learned what
changed.

The ordering itself gives a result too. Concept-first gives **0.1569**, symptom-first
in its plainest form gives **0.6667**. The gap, more than fourfold, comes not from
writing better but from **indexing the text by what the reader already holds.** The
same information, two separate headings, two separate outcomes.

## Completing the Taxonomy, and Its Limit

The last block looks at first glance like the course's closing note: **6** of six
reader questions land on a text, **0** unanswered. The second lesson drew the
taxonomy's limit with two questions; the fifth lesson closed one, this lesson closes
the other. No question the reader might bring is left uncovered.

But the top table breaks this comfort. At version twelve, **56** of **56** claims are
stale, and only **17** of them produce a symptom. The widest set troubleshooting
content can possibly cover is **17/56** — **0.3036**. The remaining **39** claims
produce no symptom at all, so no troubleshooting entry can be written for them. The
writer does not know what to write; the reader does not know what to ask.

The surface breakdown sharpens this further. On the signature surface, **17** of
**22** stale claims produce no symptom; on the concept surface, **11** of **11** produce
no symptom. The surface troubleshooting covers best is **flow**: **9** of sixteen
stale claims give a symptom. But flow is also the surface that does **not** name
itself — meaning exactly where troubleshooting has the most entries, the concept index
is entirely useless. The two tables complete each other precisely here.

What this topic's conclusion leaves is this: **all six questions land on a text, but
all the texts together still reach only 17 of the stale claims.** The taxonomy is
complete; coverage is not. Throughout this topic, the only thing that made silent
staleness visible showed up in exactly two places — being embedded in a runnable
example, and being written into release notes' meaning list. The rest can only be found
by someone going and looking for it.

## The Entry Itself Also Goes Stale

Troubleshooting content occupies a strange place among the texts in this topic:
**its reason for existing is a defect, and a defect can be fixed.** The other types aim
to stay valid for as long as the product lives; a troubleshooting entry becomes
unnecessary the moment the defect it points to is fixed.

Becoming unnecessary looks harmless. It is not. A leftover entry introduces the reader
to a symptom that no longer occurs and ties it to a cause that no longer exists. A
reader arrives with a similar but different defect, sees a nearby line of the symptom,
reaches the entry, and is convinced of the **wrong cause.** This is not an empty
result, it is a wrong one — worse than never having been written at all.

This kind of entry has a special place in the course's measure. A stale troubleshooting
entry is **silent**, because it breaks nothing: the text is read, the steps are
followed, the defect does not go away, and the reader suspects themselves. It never
occurs to them that the first text they saw for the symptom might be wrong, because
that text begins with exactly the line they saw.

A practical rule follows, and it is this topic's one maintenance rule: when a
troubleshooting entry is written, **which version it is valid for** should be written
too. The same mechanism as the superseded record in the third lesson — writing a
claim's scope moves it out of wrongness and into history.

## Summary

- A reader arriving with a symptom's index does not match the document's index: the
  document indexes by concept, the reader by symptom. Troubleshooting content is the
  text that performs this translation.
- An entry's three sections meet three reader needs: **symptom** meets recognition,
  **cause** meets cause, **remedy** meets action. Symptom has to be written in the
  form the reader **sees** it.
- Seventeen defects and three needs make **51** decisions; concept-first text meets
  **8** of them (**0.1569**), symptom-remedy meets **34** (**0.6667**),
  symptom-cause-remedy meets **51** (**1.0000**).
- Concept-first text reaches only **8** of seventeen defects: nine defects bound to the
  flow surface do not name themselves and never enter the concept index at all.
- The widest set troubleshooting can cover is **17/56** (**0.3036**); the **39**
  silently stale claims produce no symptom at all and stay outside this type too.
- **6** of six reader questions now land on a text — the taxonomy is complete, coverage
  is not.

## Next Step

Throughout this topic, texts were separated and measured by the reader's **question**;
all six questions now land on a type. But every measurement quietly assumed something:
who the reader is. "New reader," "maintainer," "someone about to touch the code" — these
roles appeared inside the lessons, never inside a document. So what happens if a text
does not say who its reader is? The next topic starts here, and its first lesson
measures exactly this question: how many of the claims still true does an unwritten
prerequisite assumption make unreadable? A sentence still being true does not mean
someone who can read it exists.
