Skip to content

fix: make docs generation alerts say why and what to do - #1124

Open
teallarson wants to merge 9 commits into
mainfrom
fix/loud-docs-generation-alerts
Open

fix: make docs generation alerts say why and what to do#1124
teallarson wants to merge 9 commits into
mainfrom
fix/loud-docs-generation-alerts

Conversation

@teallarson

@teallarson teallarson commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Why

The nightly Slack alert fired for the first time today and read like this:

⚠️ Toolkit docs generation completed with recoverable failures
Workflow run: Open run
No docs are being served (no prior output): MicrosoftUsers

Which raises every question it should answer. Why did it fail? Is that bad? What do I do? Answering it meant opening the run, expanding the log, and scrolling — and the most visible line there, ✓ MicrosoftUsers: 0 tools, points at the wrong cause. It's the placeholder's empty tool list, not the API's. The real reason, missing design-system metadata, was already in failed-tools.json and got thrown away by the jq that built the message.

Changes

The reason survives. FailedToolsReport carries recoveredToolkits: {id, recovery, reason} in place of two arrays of bare names.

The message is built in tested code. New src/alerts/docs-alert.ts plus a alert CLI subcommand that prints the payload, or nothing when a run is clean. A jq program embedded in workflow YAML can only ever repeat what it's given, and nothing tests it.

Severity is no longer flattened. An omitted toolkit has no page at all; a preserved one still serves yesterday's. They now get different headlines and ordering, with omitted first.

Each reason maps to its fix. Missing metadata points at @arcadeai/design-system and skip-toolkits.txt; curation failures point at curation/<toolkit>/.

The link lands on the failing job, not the run summary, and the full report uploads as the failed-tools artifact.

Silent failure is gone. The Slack step drops continue-on-error — it swallowed curl: (3) URL rejected against an unset webhook secret, which is exactly how this went unnoticed. The reviewer step still can't fail the run, but now annotates it instead of dying quietly (it's been failing on Resource not accessible by personal access token and nobody knew).

Same alert under this change:

:no_entry: MicrosoftUsers is missing from the docs site

*Missing entirely (no previous output)*

• *MicrosoftUsers* — missing design-system metadata
    Fix: Add a `MicrosoftUsers` entry to `@arcadeai/design-system` and bump the pin in this repo, or add it to `skip-toolkits.txt` if it is not meant to be public yet.

<...|Open the failing step> · full detail in the `failed-tools` artifact on the run

Verification

  • 526 generator tests, typecheck, and lint pass; Vale clean on the new README section.
  • Ran the alert command against a report reproducing today's failure to produce the message above, and against a missing report to confirm it stays silent.

Follow-up not included here: DOCS_PUBLISHABLE_GH_TOKEN needs reviewer permission, or the review step should go.


Note

Low Risk
Changes are limited to CI notifications, run report JSON shape, and alert formatting; no auth or docs generation logic paths are altered beyond persisting richer recovery metadata.

Overview
Toolkit docs generation alerts now carry failure reasons and fixes, instead of listing bare toolkit names in workflow YAML.

failed-tools.json replaces separate preservedToolkits / omittedToolkits arrays with recoveredToolkits entries (id, recovery, reason). New buildDocsAlert and a CLI alert command build the Slack payload in tested TypeScript—omitted toolkits lead preserved ones, with per-reason fix hints (design-system metadata, curation paths, etc.).

The generate-toolkit-docs workflow posts that payload via tsx … alert, deep-links the generate job log (actions: read), uploads the failed-tools artifact, and drops continue-on-error on the recoverable-failure Slack step so webhook misconfigurations fail loudly. The failure alert job distinguishes generation failed vs generated but a later step failed via a generation-succeeded output; PR review request failures stay non-fatal but emit ::warning.

Docs (README run-alerts section, CURATION tsx invocation note) and workflow/unit tests were updated to match.

Reviewed by Cursor Bugbot for commit 5303469. Bugbot is set up for automated code reviews on this repo. Configure here.

The nightly Slack alert named the affected toolkits and nothing else, so
"MicrosoftUsers has no docs" required reading the run log to learn that the
cause was a missing design-system entry — and the log's `0 tools` line reads
like a different problem entirely.

- Carry the failure reason into the report instead of dropping it, and build
  the message in `src/alerts/docs-alert.ts` where it can be tested. A jq
  program embedded in workflow YAML could only ever repeat toolkit names.
- Lead with omitted toolkits, which have no page at all, over preserved ones,
  which still serve their last good output.
- Map each known reason to its fix.
- Link the job log rather than the run summary, and attach the full report as
  an artifact.
- Drop `continue-on-error` from the Slack step. It swallowed a curl failure
  against an unset webhook secret, which is how the alert went unnoticed.
  The reviewer step keeps running on failure but now annotates the run.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 12, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview Aug 13, 2026 5:17pm

Request Review

Comment thread .github/workflows/generate-toolkit-docs.yml
The Slack step can now fail the job, and the alert job fires on any job
failure — so a broken webhook would announce a generation failure that never
happened, sending people to look for one.

The generate step records that it finished, and the alert job requires that
marker to be absent. A later step failing still turns the run red, which is
the visible signal it should be.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Comment thread .github/workflows/generate-toolkit-docs.yml
Actions runs `run:` steps with `-e -o pipefail`, so the job-URL lookup
could abort the step before curl and lose the alert it exists to send.
`${job_url:-$RUN_URL}` covers an empty URL, not a failed lookup, and
because generation itself succeeded the failure-alert job is suppressed —
so nothing reaches Slack.

Two ways it could fail:

- `gh api` exits non-zero (the token already hits "Resource not
  accessible" on the reviewer step, so this is not hypothetical).
- `gh api` succeeds and `| head -n 1` SIGPIPEs it, which `pipefail`
  turns into exit 141.

Select the first match in jq instead of piping to head, and fall back to
the run URL on any failure. Verified under `-e -o pipefail` that all four
outcomes — API failure, no matching job, empty job list, and a match —
now reach curl.

Reported by Cursor Bugbot on #1124.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@teallarson

Copy link
Copy Markdown
Contributor Author

Re: Bugbot's job-URL finding

Good catch, and there's a second path to the same outcome: even when gh api succeeds, | head -n 1 SIGPIPEs it, which pipefail turns into exit 141 — so this could eat the alert on the happy path too.

Fixed in f5f855b by selecting the first match in jq instead of piping to head, plus || job_url="" so a failed lookup falls back to the run URL. Verified under -e -o pipefail that API failure, no matching job, empty job list, and a match all reach curl.

— Strider 🐦‍⬛, Teal's agent · approved by Teal

Comment thread .github/workflows/generate-toolkit-docs.yml
@teallarson
teallarson marked this pull request as draft August 12, 2026 20:26
The recoverable Slack step ran last, under the default "everything so far
succeeded" gate. A failed sidebar sync or PR creation therefore skipped
it — and because generation itself succeeded, `generation-succeeded`
suppressed the failure-alert job too. Missing and stale pages went
unannounced in both directions, with the reason sitting in an uploaded
artifact nobody had a reason to open.

Gate the step on the generate step instead, which is the signal the
workflow already tracks to tell "generation broke" from "a later step
broke". `!cancelled()` rather than `always()`, since `cancel-in-progress`
cancels superseded runs and those have nothing to report.

Checked every combination of cancelled, generate outcome, and job result:
no case sends both alerts, and no case drops a recoverable report.

Reported by Cursor Bugbot on #1124.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A red run whose generate step succeeded sent nothing to Slack: the
recoverable report had nothing to say, and the alert job deliberately
excluded that case to avoid calling a failed sidebar sync a "generation
failure". So an auto-PR that never got created was visible only to
someone who happened to open the Actions tab.

Give the alert job the third case instead of excluding it. It now fires on
every failed generate job and picks wording from
`generation-succeeded`: a validation error points at the run, and a
publishing break points at sidebar sync and PR creation, and says there
may be no auto-PR to merge.

A run that recovers from a toolkit failure and then fails to publish sends
two messages, on purpose — missing pages and a broken publish are
separate things to fix.

Checked every combination of cancelled, generate outcome, job result, and
recoverable-toolkit presence: no red run is silent. Rendered both alert
bodies from the workflow's own run block to confirm valid JSON and the
right copy. README documents the three messages.

Reported by Cursor Bugbot on #1124.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The alert job now picks its headline from whether generation finished, rather
than staying silent when a later step fails. Two assertions still described the
old shape: one pinned the literal "generation failed" prefix that jq now builds
from a variable, and one pinned the `if:` guard that moved into the step body.

Both keep their original intent — that the escaping stays correct, and that a
red run after successful generation is not reported as a generation failure.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@teallarson

Copy link
Copy Markdown
Contributor Author

bugbot run

Follow-up review please — three fixes since your last pass (f5f855b, e6da31b, a3e987b) plus test updates in 38c3a4b. All three touch the Slack alert paths in .github/workflows/generate-toolkit-docs.yml.

— Strider 🐦‍⬛, Teal's agent · approved by Teal

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 38c3a4b. Configure here.

…ion-alerts

# Conflicts:
#	toolkit-docs-generator/README.md
@teallarson

Copy link
Copy Markdown
Contributor Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 34d49f3. Configure here.

@teallarson
teallarson marked this pull request as ready for review August 13, 2026 16:54

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 346f4ff. Configure here.

Comment thread .github/workflows/generate-toolkit-docs.yml Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants