Add Spectrum troubleshooting docs for top support case drivers#30683
Add Spectrum troubleshooting docs for top support case drivers#30683stechedo wants to merge 8 commits into
Conversation
|
Hey there, we've marked this pull request as stale because there's no recent activity on it. This label helps us identify PRs that might need updates (or to be closed out by our team if no longer relevant). |
959bdcb to
f311329
Compare
Review
Fix in your agentFix the following review findings in PR #30683 (https://github.com/cloudflare/cloudflare-docs/pull/30683).
Before making changes, review each finding and present a brief summary table:
- For each finding, state whether you agree, disagree, or need clarification
- If you disagree (e.g. the fix requires disproportionate effort for minimal benefit,
or the finding is factually incorrect), explain why
- If you need clarification before deciding, ask those questions
- Then share your plan for which issues to tackle and in what order
After triaging, fix all legitimate findings. For any you decide to skip,
post a comment on this PR with the finding ID and your reasoning.
---
## Code Review
### Warnings (11)
#### CR-4050399fb6c0 · Misleading cross-reference
- **File:** `src/content/docs/spectrum/reference/troubleshooting.mdx` line 63
- **Issue:** Line 63 promises more details about the DNS-record conflict limitation and links to `/spectrum/reference/limitations/`, but the Limitations page does not mention this restriction.
- **Fix:** Either add the DNS-record conflict limitation to `src/content/docs/spectrum/reference/limitations.mdx` or remove the promise of more details and point the link elsewhere.
#### CR-9746e1fd141a · Unguarded custom element registration
- **File:** `src/components/AiSearchIndexingDiagram.astro` line 889
- **Issue:** `customElements.define("cfdocs-ai-search-indexing-diagram", ...)` is called unconditionally. If the script is evaluated more than once (e.g., during HMR, in tests, or if the script is otherwise duplicated), the custom element registry throws `NotSupportedError`.
- **Fix:** Make the registration idempotent: `if (!customElements.get("cfdocs-ai-search-indexing-diagram")) { customElements.define(...); }`.
#### CR-b72d87deb669 · Detached element timer leak
- **File:** `src/components/AiSearchQueryingDiagram.astro` line 789
- **Issue:** `disconnectedCallback()` only clears the single pending `this.timer`. A timeout callback that is already queued can still run after the element is removed, call `advance()`, and schedule new timers against a detached DOM tree.
- **Fix:** Guard `advance()` (and the initial `play()` callback) with a `this.isConnected` check, or clear/reset timers when disconnected and avoid scheduling further work.
#### CR-a65044b3f463 · Resource leak on failure path
- **File:** `.flue/workflows/finalize-review.ts` line 146
- **Issue:** When stream results are missing, cleanupPending is awaited then the function returns. But the agent session (created later) is irrelevant here. However, early returns after step 1 (e.g., context missing at line 101, stream missing at 147, PR fetch failed at 177, head moved at 191) leave no created session. The only real resource is the R2 bucket reads. Not a concern.
However, when reconcileStream throws and we catch at lines 332-350, the function continues. That's intended degradation. Not a finding.
Main concern: in step 8, markAutoReviewCompleted failure is caught and logged, but finalize continues and reports success. This silently leaves the auto-review slot unconsumed, which could cause the user to be re-billed/re-reviewed unexpectedly. This is error swallowing but explicitly logged as a non-fatal operation. Could be a warning.
Also: line 438 `await session.delete().catch(() => {});` swallows session deletion errors silently, but that's minor.
More significant: `parsePayload` does not validate `number > 0`, `headSha` nonempty, `dispatchId` nonempty. However that's standard weak validation. Could be a suggestion.
Most concrete issue: Late resource cleanup. When `init(agent)` at line 287 creates a harness/session and any later early return (after session creation) would leave the session active. Looking at code, after line 291 there are no early returns possible, except reconciler degradation which doesn't return. Actually there are no early returns after session creation. So OK.
Wait - line 101 context missing returns before session creation. Good.
Line 147 stream missing returns before session. Good.
Line 177 PR fetch failed returns before session. Good.
Line 191 head moved returns before session. Good.
Line 249 already finalized returns before session. Good (session created at 287 after).
After session creation, reconcileStream has try-catch so never throws or returns early in the outer function. So session always deleted at 438.
The most concrete finding: In idempotency guard (comment mode), if `getIssueComments` fails, it sets allComments=[] and continues. This means the botComment search will not find an existing finalization comment, so it will re-post. This is intended per comment, but if failure is frequent, duplicate comments could appear. Acceptable.
Another concern: In `parsePayload`, `input.number` is only checked typeof number, not finite/integer. Passing `NaN` or `Infinity` slips through, causing NaN in R2 keys and string interpolations. Concrete weak validation issue.
Also `input.headSha` not checked against hex string; arbitrary string becomes R2 key. Could be suggestion.
I think the cleanest finding is: markAutoReviewCompleted failure is logged and swallowed, allowing finalize to succeed while the slot remains unconsumed, which could trigger unintended re-reviews.
- **Fix:** Consider returning a failure/non-finalized reason when markAutoReviewCompleted fails, or queue a retry, since an unconsumed auto-review slot may cause duplicate/unintended reviews.
#### CR-a49b1d2042d9 · Streaming snippet does not consume stream
- **File:** `src/content/catalog-models/anthropic-claude-sonnet-5.json` line 410
- **Issue:** The `stream: true` TypeScript example assigns `env.AI.run(...)` to `response` and only calls `console.log(response)`. When streaming is enabled this returns a stream/response object, so logging it does not produce the streamed text shown in `output.text`.
- **Fix:** Update the TypeScript streaming snippet to consume the stream (for example, iterate over chunks or read `response.body`) so the example matches the rendered output.
#### CR-205ecfa2f49f · Added lines can be silently dropped
- **File:** `.flue/lib/code-review-inproc.ts` line 76
- **Issue:** The header-skip checks in parseAddedLines (e.g. raw.startsWith("+++ b/")) run on every patch line, not just on real file headers before the first hunk. An added line whose source content starts with "++ b/", "++ a/", etc. will appear in the patch as "+++ b/..." and be skipped, so it never reaches the reviewer.
- **Fix:** Track whether a hunk header has been seen and only apply the ---/+++ header skip rules before the first hunk.
#### CR-790138ed0478 · Timeout flag race misclassifies later errors
- **File:** `.flue/lib/code-review-inproc.ts` line 465
- **Issue:** If the per-file timer fires while handle has already resolved, timedOut is set to true but the function may still proceed to process the result. If any subsequent step (e.g. assignCodeReviewFindingIds) throws, the catch block reports it as a timeout instead of the real error.
- **Fix:** Reset timedOut = false immediately after await handle succeeds, before processing the result.
#### CR-86f40bf1274b · Finalize lock stuck on admission failure
- **File:** `.flue/lib/finalize-rendezvous.ts` line 391
- **Issue:** After `tryClaimFinalize` wins the conditional PUT, `admitWorkflow` is awaited outside the try/catch. If it throws, the `finalize.lock` object remains in R2 and no other specialist can claim it, so `finalize-review` is never admitted for this dispatch.
- **Fix:** Either wrap admission in a retry with exponential backoff, or delete/reset the lock in the admission error path so another retry can take over.
#### CR-45351e1f8985 · Self-stream final state not verified
- **File:** `.flue/lib/finalize-rendezvous.ts` line 203
- **Issue:** `tryClaimFinalize` checks that every sibling stream is `final: true`, but never verifies that the caller's own stream result exists and is final before racing for the lock.
- **Fix:** Verify `myStream`'s own payload is final in `tryClaimFinalize`, so the function is safe when called outside of `reportSpecialistResult` or after a delayed R2 read-your-write consistency window.
#### CR-ea45836bc4bb · Inconsistent example output
- **File:** `src/content/catalog-models/anthropic-claude-opus-4.8.json` line 508
- **Issue:** The added "Web Search" example's `output.text` only contains "I'll search for the latest Cloudflare news this week.", but the `raw_response.content` array (lines 688-792) contains the actual final answer with the three news bullets, tool-result payloads, and citations. The example output does not reflect the real model response it is paired with, making the catalog entry misleading.
- **Fix:** Update `output.text` to contain the complete final response text from the `raw_response` (the three bullets and closing sentence), matching how the other examples populate the `output` field.
#### CR-8c6d3f362c23 · Example output incomplete
- **File:** `src/content/catalog-models/anthropic-claude-haiku-4.5.json` line 481
- **Issue:** `output.text` is set to "Let me search for more recent news from this week specifically.", but the surrounding `raw_response.content` continues with the web_search tool result and a final answer beginning "Based on the latest news from this week..." (line 653). Other examples keep `output.text` aligned with the full assistant response.
- **Fix:** Update `output.text` to contain the final assistant answer, or adjust the example data so the output and raw_response represent the same turn.
### Suggestions (3)
#### CR-5da00f3a901d · Reduced motion animation not suppressed
- **File:** `src/components/AiSearchIndexingDiagram.astro` line 796
- **Issue:** The `@media (prefers-reduced-motion: reduce)` block removes transitions but does not suppress the `asid-pulse` keyframe animation on `.asid-node.current`. A user who toggles reduced motion after mount, or whose preference is missed by the one-time JS check, will still see the continuous pulse.
- **Fix:** Add `.asid-node.current { animation: none; }` inside the reduced motion media query. Consider also listening for `change` on the `matchMedia` query so the component reacts to live preference changes.
#### CR-52aaf6ceb860 · New web component directory convention
- **File:** `src/components/AiSearchIndexingDiagram.astro`
- **Issue:** The new web component is added as a flat file, `src/components/AiSearchIndexingDiagram.astro`. AGENTS.md directs new web components to be placed in `src/components/{component-name}/` directories.
- **Fix:** Move the component into `src/components/ai-search-indexing-diagram/` and update the barrel import in `src/components/index.ts` to match.
#### CR-c0ce4fd12e7d · Unused CSS custom property
- **File:** `src/components/AiSearchVoiceDiagram.astro` line 173
- **Issue:** `--asvd-accent-soft` is defined but never referenced anywhere in the component's CSS or markup.
- **Fix:** Remove the unused `--asvd-accent-soft` declaration or apply it where intended for consistency with the other AI Search diagrams.
---
## Conventions
### Warnings (1)
#### CV-8436dbf55b99 · Scope accuracy
- **File:** PR-level finding
- **Issue:** Description claims five modified pages including /spectrum/reference/limitations/ and /load-balancing/additional-options/spectrum/, but changedFiles does not include those paths.
- **Fix:** Update the Changes section to reflect the files actually modified in the PR, or add the omitted files if they were intended to be changed.
Code ReviewThis code review is in beta and may not always be helpful — use your judgment. Warnings (11)
Suggestions (3)
ConventionsWarnings (1)
Style Guide ReviewNo style-guide issues found. CommandsOnly codeowners can run commands. Post a comment with the command to trigger it.
|
f311329 to
4e5ee85
Compare
ea9679c to
ad01610
Compare
|
Thanks Stephen, have reviewed. Could we just hold the IP Access Rules + health checks section? I need a bit more time to verify the mechanism, but I don't want to block everything else. For the rest: 1. Same-hostname clarification (opencode picked up the below) Thanks! |
…split health checks Per review feedback on cloudflare#30683: - Move the 'Health checks fail when IP Access Rules are enabled' section and related callouts to a separate PR (cloudflare#32137) so this PR isn't blocked while the mechanism is verified. - Clarify that the DNS record conflict is specifically between a manually-created proxied record and a Spectrum application, not between Spectrum applications themselves. Multiple Spectrum applications (including a mix of HTTP/HTTPS and TCP/UDP) can share a hostname because Spectrum manages the DNS record for each. - Align the double-proxy caution in configuration-options.mdx with the troubleshooting page: TCP applications surface a failed origin TLS handshake as 521/522, not error 525, which is HTTP/HTTPS-app specific.
|
Thanks for the review — pushed changes addressing both items, plus split out the held section. 1. Same-hostname clarificationUpdated 2. Error 525 inconsistencyAligned the double-proxy caution in Held section moved to a new PRSplit the "Health checks fail when IP Access Rules are enabled" content (troubleshooting.mdx section, the two callouts in configuration-options.mdx, and the Monitors-step callout in load-balancing/spectrum.mdx) out to #32137, so it doesn't block the rest of this PR while the mechanism is verified. Re: the automated code review findings posted aboveThose findings (CR-9746e1fd141a, CR-b72d87deb669, CR-a65044b3f463, CR-a49b1d2042d9, CR-205ecfa2f49f, CR-790138ed0478, CR-86f40bf1274b, CR-45351e1f8985, CR-ea45836bc4bb, CR-8c6d3f362c23, CR-5da00f3a901d, CR-52aaf6ceb860, CR-c0ce4fd12e7d) all reference files that are not part of this PR's diff ( |
…se drivers Based on analysis of April 2026 Network SBR cases, add documentation to address the top 3 case-generating Spectrum issues: 1. IP Access Rules + Health Checks interaction: Customers enable IP Access Rules on Spectrum apps, then Cloudflare health checks fail because probe IPs are blocked. Added warnings to configuration-options and load-balancing/spectrum pages. 2. Same hostname for WAF + Spectrum: Customers attempt to use the same hostname for HTTP (WAF) and TCP (Spectrum) on different ports. This is a platform limitation. Added new section to limitations page and cross-reference on DNS troubleshooting page. 3. Edge TLS / Protocol mismatch: Customers configure HTTP edge ports expecting HTTPS to origin. Spectrum does not upgrade protocols. Added warnings to Edge TLS Termination section. Also: - Created new /spectrum/reference/troubleshooting/ page with structured symptom/cause/solution sections for all three issues plus error 525 and common status code patterns - Added note to /spectrum/reference/logs/ clarifying that Spectrum status codes are distinct from HTTP status codes
Fix style guide violations flagged by cloudflare-docs-bot:
- Use 'turn on' instead of 'enable' for toggles
- Use bullet points for unordered causes, numbered list for sequential steps
- Remove -ing verb from heading ('Understanding common...' -> 'Common...')
- Replace 'the table below' with direct reference
- Replace 'etc.' with 'and similar'
- Monospace DNS record types (A, AAAA, CNAME)
- Add introductory sentence before status code table
- Convert two-item symptom list to prose
- Fix TLS mode guidance to specify Full/Full (Strict) instead of generic 'enabled'
- Fix broken cross-links to removed limitations.mdx anchors
- Reframe error 525 section around TLS handshake failures with Spectrum event log code 540, clarify HTTP 525 applies only to HTTP/HTTPS-type applications - Update DNS records-with-same-name cross-link to point to the troubleshooting page (which documents the workaround) instead of the limitations page (which does not) - Monospace status code examples (444, 499) in logs.mdx - Update anchor in configuration-options.mdx to match renamed heading
…ection Replace 540 (client/edge TLS failure) with origin-side error codes 520/521/522 which correctly describe edge-to-origin connection failures. 540 refers to the client-to-edge handshake per the Spectrum logs reference, not edge-to-origin.
Separate TCP and HTTP/HTTPS symptoms: Edge TLS Termination applies to TCP apps (origin errors 521/522), while error 525 applies to HTTP/HTTPS apps. Avoids conflating transport-level connection codes with TLS handshake failures.
Spectrum has no dedicated origin-side TLS handshake status code. A failed TLS handshake at the origin is reported as an origin connection failure (521/522). Added explanation and cross-link to the Event logs reference.
…split health checks Per review feedback on cloudflare#30683: - Move the 'Health checks fail when IP Access Rules are enabled' section and related callouts to a separate PR (cloudflare#32137) so this PR isn't blocked while the mechanism is verified. - Clarify that the DNS record conflict is specifically between a manually-created proxied record and a Spectrum application, not between Spectrum applications themselves. Multiple Spectrum applications (including a mix of HTTP/HTTPS and TCP/UDP) can share a hostname because Spectrum manages the DNS record for each. - Align the double-proxy caution in configuration-options.mdx with the troubleshooting page: TCP applications surface a failed origin TLS handshake as 521/522, not error 525, which is HTTP/HTTPS-app specific.
426e94b to
effc1d7
Compare
Summary
Adds a new Spectrum Troubleshooting page and improves existing Spectrum documentation to address the top 3 case-generating issues identified in the April 2026 Network Support-by-Request (SBR) case review (~190 cases analyzed).
Estimated case deflection: 9-13 cases/month across these 3 issues.
Changes
New page
/spectrum/reference/troubleshooting/— New troubleshooting page with structured symptom/cause/solution sections covering:Modified pages (5)
/spectrum/reference/configuration-options/— Added warnings about IP Access Rules blocking health checks, Custom Rules not working with Spectrum, protocol upgrade not being supported, and double-proxy chains causing 525 errors. Expanded intro paragraph to clarify Spectrum's L4 pass-through behavior./spectrum/reference/limitations/— Added new "IP access control" section and "Using the same hostname for HTTP proxy and Spectrum" section documenting the platform limitation and recommending split-hostname architecture (with Citrix Gateway use case)./spectrum/reference/logs/— Added note clarifying that Spectrum status codes are distinct from HTTP status codes, with cross-link to troubleshooting page./load-balancing/additional-options/spectrum/— Added caution callout in the Monitors setup step warning about IP Access Rules blocking health checks./dns/manage-dns-records/troubleshooting/records-with-same-name/— Added note explaining that DNS record conflicts also apply to Spectrum applications, with cross-link to Spectrum limitations.Motivation
These documentation gaps were identified by reviewing all April 2026 Network SBR cases. The top case-generating patterns were:
Content area
Spectrum, Load Balancing, DNS