Files
coder/docs/support/support-bundle.md
T
Nick Vigilante 0a7bb80a1e feat: make CLI/API doc generators emit front-matter metadata (Phase 2) (#27246)
## Summary

Phase 2 of the H1 → front-matter migration (`DOCS-483`; parent
`DOCS-477`). Makes the two reference-doc generators emit per-page
metadata as YAML front matter instead of a leading `# H1`, so generated
pages are self-describing and `make gen` stops reverting migrated pages
(Phase 3).

Phase 1 (`DOCS-482`) made the coder.com renderers prefer a front-matter
`title` (manifest fallback).

> [!NOTE]
> Rebased onto `main` and fully regenerated, and updated across two
rounds of Coder Agents Review — see **Review follow-ups** below.

## Changes

- **`scripts/clidocgen/command.tpl` + `gen.go` + `main.go`** — front
matter now carries `title` (from `fullName`) and `description` (from the
command's `Short`), and the leading `# H1` is dropped. The CLI index
page's front matter is taken from the manifest `Command Line` route
(title/description/icon_path).
- **`scripts/apidocgen/postprocess/main.go`** — reads the manifest and,
at write time, injects front matter carrying each section's `title` plus
any curated `description`, `state`, and `icon_path`. The API index
page's front matter is taken from the manifest `REST API` route.
- **`scripts/docgenenv`** (new shared code) — one `YAMLScalar`
front-matter escaper, one `Route`/`Manifest` schema +
`LoadManifest`/`FindRoute`, and one `FrontMatter(Route)` emitter, all
imported by both generators (no duplicated helpers, types, or emitters).
- Regenerated all **166 CLI + 31 API** reference pages.

### Metadata → front matter, and what stays in the manifest

Every *per-page* manifest field is mirrored into the page's front
matter: `title`, `description`, `state`, `icon_path`. The **structural**
fields stay in `manifest.json`:

- `children` — the nav tree (explicitly out of scope).
- `path` — the manifest's pointer to the file; a page carrying its own
path is redundant/error-prone, so it's treated like `children`.

The fields are **duplicated** into front matter and **`manifest.json` is
left unchanged**, so this is a **no-op for rendering today** (coder.com
strips front matter for `llms`, and Algolia + the renderer read only
`title`). Removing the fields from the manifest is the natural
follow-up, gated on the renderer reading them from front matter first.

### Why the API side changes the postprocessor, not the `.dot` templates

The issue text suggested editing
`scripts/apidocgen/markdown-template/*`. I deliberately did **not**,
because the postprocessor derives each page's **filename, section title,
and manifest route** from the leading `# {name}` line
(`extractSectionName`). Emitting front matter from the template would
break that extraction. Instead the widdershins templates still emit `#
{name}`, the postprocessor reads it (and now verifies it), and then
swaps the heading for a front-matter block as each section is written.

## Review follow-ups (Coder Agents Review)

### Round 1 — addressed in `e53d5e03` (all threads resolved)

- **CRF-1 / CRF-4** — de-duplicated the escaper and the
`route`/`manifest` schema + traversal into `scripts/docgenenv` (shared
by both generators).
- **CRF-2** — `YAMLScalar` now quotes YAML-reserved scalars
(`true/false/null/…`, numbers); no current value is affected.
- **CRF-3** — added unit tests: a `YAMLScalar` round-trip, `FindRoute`,
and `prependFrontMatter`.
- **CRF-5** — the CLI and API **index** pages now mirror their manifest
route's title/description/icon_path instead of a hardcoded
`coder`/`API`, fixing a rendered-heading regression (`REST API`/`Command
Line` were being overwritten).
- **CRF-6** — dropped the dead `#login` anchor in
`docs/support/support-bundle.md` (the migrated `login.md` no longer
mints that heading anchor).
- **CRF-7 / CRF-8 / CRF-11** — renamed to `prependFrontMatter`, switched
to `bytes.Cut`, and it now strips the first line only when it is the `#
{name}` heading (`extractSectionName` errors otherwise).
- **CRF-9** — removed the orphan `docs/reference/api/chat.md` (not in
the manifest, not linked; the real page is `chats.md`).
- **CRF-10** — the metadata read and the manifest rewrite now share one
`FindRoute` traversal.
- **CRF-13** — moot under squash-merge; this branch is a single
scopeless commit.
- **CRF-15** — the pre-existing `sort.Slice`/`slices.IsSorted`
comparator is left as-is per the review (out of scope; safe today
because section names are unique).

### Round 2 — addressed in `ee796e7107` (all threads resolved)

- **CRF-16** (P1) — removed three em-dashes from new doc comments (the
only `make lint` failure on the prior head); the emdash gate is green.
- **CRF-17 / CRF-18** — unified front-matter emission into one shared
`docgenenv.FrontMatter(Route)`, used by the API postprocessor directly
and by `command.tpl` via a `frontMatter` template func. This retires the
hand-written template YAML and the
`indexTitle`/`indexDescription`/`indexIconPath` closures, so a new
front-matter field is wired in one place, and it gives the CLI index the
`state` arm it previously lacked. Verified byte-identical: a full CLI +
API regen produces zero page changes.
- **CRF-19** — CLI child sort switched to `slices.SortFunc` +
`cmp.Compare` (typed comparator).
- **CRF-20** — reworded the `prependFrontMatter` comment:
`extractSectionName`'s fail-fast is the load-bearing guard; the prefix
check is a defensive backstop.
- **CRF-21** — added `icon_path`/`state` coverage in `docgenenv`'s
`TestFrontMatter/AllFields` (the branch the index page relies on,
previously at 0%).
- **CRF-22** — `YAMLScalar` no longer emits a trailing-space value as a
bare scalar (YAML strips it on read, so it would not round-trip); added
test coverage.
- **CRF-24** — the shared emitter removed the duplicated `cliIndexRoute`
doc comment; the rationale now lives in one place.
- **CRF-23** (Phase 3, out of scope here) — noted: the API generator
wipes and regenerates `reference/api/` from the manifest, so removing
curated metadata from the manifest in Phase 3 needs another source first
(a generator that preserves existing front matter, or metadata carried
alongside the swagger annotations).
- **Process (Mafu-san)** — the verification set below now leads with
`make lint`, the mandatory CI gate that the earlier list omitted.

## Cross-repo dependency

**Resolved — this PR no longer has a hard merge-ordering gate** (CRF-14
was right; the earlier "must merge after #968" note was stale).

The coder.com surfaces that would otherwise leak raw front matter from
`coder/coder` `main` are already front-matter-aware on merged PRs:

- **coder.com#964** (`DOCS-554`, llms-full.txt corpus + Algolia) —
**merged**.
- **coder.com#974** (`DOCS-574`, the `.md` proxy twin + `llms.txt` index
titles) — **merged**.

coder.com#968 (`DOCS-577`) was re-scoped to only the renderer
route-metadata generalization; it's a no-op on today's corpus and its
own description confirms the "deploy before the generators" constraint
no longer applies (that was driven by the llms corpus, now in #964).
Worth a final confirmation that #964/#974 are **deployed** before merge,
but there's no branch/PR ordering blocker left.

## Verification & evidence

AI was the primary author of this PR (see disclosure below); per the [AI
Contribution
Guidelines](https://coder.com/docs/about/contributing/AI_CONTRIBUTING)
here is manual verification.

- `make lint` (golangci-lint + the emdash gate) passes; `go build` / `go
vet` / `go test` are clean for the generators + `scripts/docgenenv`;
`pnpm check-docs` passes.
- `swagger.json`, `docs.go`, and `manifest.json` are **unchanged** —
metadata is duplicated into front matter; command/section names and
routes did not move.
- The diff is purely additive front matter
(`title`/`description`/`state`/`icon_path`) + the leading H1 removal; no
body reflow. A full CLI + API regen produces **zero** page changes
beyond the two index pages.

<details>
<summary>Terminal evidence</summary>

CLI `description` from the command's `Short` (`YAMLScalar` quotes when
needed, e.g. a `Short` with a colon):

```md
---
title: server
description: Start a Coder server
---
```

API pages inherit curated manifest metadata (only Agents/Chats have any
today):

```md
---
title: Chats
description: "REST endpoints for Coder Agents Chats API (programmatic agent sessions)."
state:
  - early access
---
```

Diff scope + "no body changes" proof (uses an explicit `base..HEAD`
range, so it actually tests the claim):

```
$ git diff --shortstat origin/main
 210 files changed, 1447 insertions(+), 344 deletions(-)
# = 166 CLI + 31 API reference pages + generators + scripts/docgenenv
# swagger.json / docs.go / manifest.json: NOT modified

# Every removed line under docs/reference is a leading "# H1"; nothing else:
$ git diff origin/main..HEAD -- docs/reference/ | grep '^-' | grep -v '^---' | grep -v '^-# '
(empty)

$ pnpm check-docs
Summary: 0 error(s)
```

</details>

Linear: DOCS-483

> This PR was created with AI assistance (Coder Agents).
2026-08-11 15:22:55 +00:00

11 KiB

Generate and upload a Support Bundle to Coder Support

When you engage with Coder support to diagnose an issue with your deployment, you may be asked to generate and upload a "Support Bundle" for offline analysis. This document explains the contents of a support bundle and the steps to submit a support bundle to Coder staff.

What is a Support Bundle?

A support bundle is an archive containing a snapshot of information about your Coder deployment.

It contains information about the workspace, the template it uses, running agents in the workspace, and other detailed information useful for troubleshooting.

It is primarily intended for troubleshooting connectivity issues to workspaces, but can be useful for diagnosing other issues as well.

While we attempt to redact sensitive information from support bundles, they may contain information deemed sensitive by your organization and should be treated as such.

A brief overview of all files contained in the bundle is provided below:

Note

Detailed descriptions of all the information available in the bundle is out of scope, as support bundles are primarily intended for internal use.

Filename Description
agent/agent.json The agent used to connect to the workspace with environment variables stripped.
agent/agent_magicsock.html The contents of the HTTP debug endpoint of the agent's Tailscale Wireguard connection.
agent/client_magicsock.html The contents of the HTTP debug endpoint of the client's Tailscale Wireguard connection.
agent/listening_ports.json The listening ports detected by the selected agent running in the workspace.
agent/logs.txt Active agent log plus rotated agent logs modified in the last 24 hours, capped at 100 MiB.
agent/workspace_files/collection_errors.txt Workspace file entries dropped while assembling the bundle, such as entries exceeding the size budget. Only present when entries were dropped.
agent/workspace_files/files/ Files collected from inside the remote workspace with --workspace-file. Only present when workspace paths are requested.
agent/workspace_files/manifest.json Describes the remote workspace file collection: requested patterns, collected files, per-path errors, truncation, and applied limits. Only present when workspace paths are requested.
agent/manifest.json The manifest of the selected agent with environment variables stripped.
agent/startup_logs.txt Startup logs of the workspace agent.
agent/prometheus.txt The contents of the agent's Prometheus endpoint.
cli_logs.txt Logs from running the coder support bundle command.
deployment/buildinfo.json Coder version and build information.
deployment/config.json Deployment configuration, with secret values removed. Requires Owner role.
deployment/experiments.json Any experiments currently enabled for the deployment.
deployment/health.json A snapshot of the health status of the deployment. Requires Owner role.
logs.txt Logs from the codersdk.Client used to generate the bundle.
network/connection_info.json Information used by workspace agents used to connect to Coder (DERP map etc.)
network/coordinator_debug.html Peers currently connected to each Coder instance and the tunnels established between peers. Requires Owner role.
network/netcheck.json Results of running coder netcheck locally.
network/tailnet_debug.html Tailnet coordinators, their heartbeat ages, connected peers, and tunnels. Requires Owner role.
workspace/build_logs.txt Build logs of the selected workspace.
workspace/workspace.json Details of the selected workspace.
workspace/parameters.json Build parameters of the selected workspace.
workspace/template.json The template currently in use by the selected workspace.
workspace/template_file.zip The source code of the template currently in use by the selected workspace.
workspace/template_version.json The template version currently in use by the selected workspace.
vscode-logs/ Only present when generated from the VS Code Coder Remote extension. Includes logs, redacted settings, and local telemetry files.

How do I generate a Support Bundle?

  1. Ensure your deployment is up and running. Generating a support bundle requires the Coder deployment to be available.

  2. Ensure you have the Coder CLI installed on a local machine. See installation for steps on how to do this.

    Note

    It is recommended to generate a support bundle from a location experiencing workspace connectivity issues.

  3. Ensure you are logged in to your Coder deployment. Any authenticated user can generate a support bundle. Users with the Owner role will get the most complete bundle; non-admin users will still get a useful bundle but some admin-only data will be omitted (see the note below).

  4. Run coder support bundle [owner/workspace], and respond yes to the prompt. The support bundle will be generated in the current directory with the filename coder-support-$TIMESTAMP.zip.

    If you use VS Code, you can also run Coder: Create Support Bundle from the Command Palette. The VS Code Coder Remote extension runs coder support bundle and appends recent VS Code diagnostics to the generated archive. Bundles created with the CLI alone do not include vscode-logs/. Learn more about VS Code diagnostics.

    Note

    While support bundles can be generated without a running workspace, it is recommended to specify one to maximize troubleshooting information.

    To collect workspace-side files such as editor or service logs, add one --workspace-file flag for each path or glob. This is explicit opt-in. The CLI sends each value to the workspace agent, so quote globs to prevent your local shell from expanding them:

    coder support bundle my-workspace \
      --workspace-file '$HOME/.vscode-server/data/logs/**/*.log' \
      --workspace-file '$HOME/.local/share/code-server/coder-logs/**/*.log'
    

    Workspace paths and globs are evaluated by the workspace agent. Environment variables such as $HOME expand in the workspace, and ~/ resolves against the agent user's home directory; any absolute path in the workspace can be requested. Symlinks are followed for directly requested paths, but not during glob traversal. Collection is limited to 10000 files and 100 MiB in total; files larger than 10 MiB are truncated to their last 10 MiB and marked as truncated in the manifest. Collected files are stored under agent/workspace_files/files/, and collection metadata is stored in agent/workspace_files/manifest.json.

    Warning

    Workspace files can contain tokens, credentials, source code, or other sensitive data. Extract and review agent/workspace_files/ before sharing the bundle.

  5. (Recommended) Extract the support bundle and review its contents, redacting any information you deem necessary.

  6. Coder staff will provide you a link where you can upload the bundle along with any other necessary supporting files.

    Note

    It is helpful to leave an informative message regarding the nature of supporting files.

Coder support will then review the information you provided and respond to you with next steps.