Skip to content

fix(website): read the crawler config back from the right endpoint - #5394

Merged
fb55 merged 4 commits into
mainfrom
fix/crawler-readback
Aug 7, 2026
Merged

fix(website): read the crawler config back from the right endpoint#5394
fb55 merged 4 commits into
mainfrom
fix/crawler-readback

Conversation

@fb55

@fb55 fb55 commented Aug 3, 2026

Copy link
Copy Markdown
Member

The sync now works — but its verification step never ran:

Synced crawler configuration to e44e1737-…
Could not read the config back (404); skipping verification.

There is no GET /1/crawlers/{id}/config. The check built to catch a bad sync
was quietly doing nothing, which is how it went unnoticed for three runs.

  • Read the crawler with ?withConfig=true and unwrap the response (data) and
    its config, which may arrive as a JSON string.
  • A 404 now fails the job. It means the URL is wrong rather than the service
    being unwell, and a verification step that silently no-ops is worse than not
    having one. Transient failures still warn without failing.

Not yet verified end to end

The PATCH path is confirmed working in CI. The read-back path is not — it needs
the crawler API key, which I do not have. Before merging, this settles it in one
command:

cd website && CRAWLER_USER_ID=be0ada85-2fed-440f-a059-c928f230ed2b \
  CRAWLER_API_KEY=<key> npm run sync:crawler

Expected: Verified: the stored configuration matches this repo.
It is idempotent — it pushes the same config that is already live.


🤖 created by Claude Opus 5

The sync succeeded but logged "Could not read the config back (404);
skipping verification" — there is no GET on /config, so the check that
exists to catch a bad sync had quietly done nothing.

Read the crawler with ?withConfig=true instead, unwrapping the response
and its config string. A 404 now fails the job: it means this URL is
wrong rather than the service being unwell, and a verification step that
silently no-ops is worse than not having one.
Copilot AI lite review requested due to automatic review settings August 3, 2026 15:45
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@fb55, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 32 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: e7f76493-1932-4171-b4fa-6579f14cd987

📥 Commits

Reviewing files that changed from the base of the PR and between 372fd28 and d8201c0.

📒 Files selected for processing (1)
  • website/scripts/sync-algolia-crawler.mjs
📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes
    • Improved crawler configuration verification after synchronization.
    • Added clearer handling for network failures, temporary service issues, and invalid responses.
    • Ensured successful responses and encoded configurations are correctly interpreted before verification.
    • Prevented non-retryable response errors from being silently overlooked, while continuing to tolerate temporary service interruptions.

Walkthrough

The crawler synchronization script reads configuration from the crawler endpoint with withConfig=true. It handles network and HTTP failures, unwraps data, parses string-encoded configuration, and compares the result.

Changes

Crawler verification

Layer / File(s) Summary
Crawler configuration read-back
website/scripts/sync-algolia-crawler.mjs
The script fetches configuration from the crawler endpoint. Network errors, 5xx responses, and 429 responses skip verification with warnings. Other 4xx responses throw errors. Successful responses unwrap data and parse string-encoded configuration before comparison.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

  • cheeriojs/cheerio#5393: Both changes modify crawler configuration read-back verification and normalize API responses before comparison.

Suggested reviewers: copilot

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely identifies the endpoint correction for crawler configuration read-back verification.
Description check ✅ Passed The description directly explains the endpoint correction, response parsing, error handling, and verification limitations.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/crawler-readback

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes the crawler-config verification step in the website’s Algolia crawler sync script by reading the configuration back from the correct API shape (crawler read with withConfig=true) and making a bad read-back endpoint (404) fail the job instead of silently skipping verification.

Changes:

  • Switches verification read-back from GET /config to GET /crawlers/{id}?withConfig=true.
  • Unwraps the read-back payload (data) and supports config arriving as a JSON string.
  • Treats a 404 on read-back as a hard failure to prevent silent no-op verification.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread website/scripts/sync-algolia-crawler.mjs Outdated
Comment thread website/scripts/sync-algolia-crawler.mjs Outdated

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@website/scripts/sync-algolia-crawler.mjs`:
- Around line 137-140: Update the read-back fetch in the sync flow around
readBack to catch transport errors such as timeouts or network failures, warn,
and continue processing; preserve the existing hard-failure behavior for HTTP
404 responses. Add coverage that mocks fetch rejection and verifies the warning
and continued execution.
- Around line 153-154: Update the read-back handling around readBack.ok to throw
an error for non-retryable 4xx responses instead of warning and continuing.
Preserve the existing verification flow for successful responses and retry
behavior for retryable failures, ensuring the sync job cannot complete
successfully when verification receives a non-retryable response.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: ac829fa9-b9b9-40a6-9ede-281a5d698cbb

📥 Commits

Reviewing files that changed from the base of the PR and between d895833 and f9523d5.

📒 Files selected for processing (1)
  • website/scripts/sync-algolia-crawler.mjs

Comment thread website/scripts/sync-algolia-crawler.mjs Outdated
Comment thread website/scripts/sync-algolia-crawler.mjs Outdated
Review of the previous commit found the same weakness it was fixing, in
the paths it did not cover:

- A transport failure (timeout, reset) rejected `fetch` and fell through
  to the outer catch, failing the deploy over a blip that says nothing
  about the config the API had already accepted. It now warns and
  continues, matching how a 5xx is treated.

- 401/403 only warned, so credentials that can PATCH but not read would
  have skipped verification silently — exactly how the wrong endpoint
  survived three runs. Non-retryable 4xx now fails; 429 still warns.

- A non-JSON body threw a bare SyntaxError with no indication of what
  was being parsed. It now names the URL and attaches the cause.

Each branch was exercised against a stubbed API: match verifies, drift
fails, transport/timeout/503 warn and continue, 403/404/bad JSON fail.
Copilot AI review requested due to automatic review settings August 6, 2026 13:43

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@website/scripts/sync-algolia-crawler.mjs`:
- Around line 170-184: Move the readBack.json() call into the existing try block
that handles configuration parsing in the read-back flow. Ensure JSON body parse
failures use the same error handling as crawler.config parsing, preserving
readBackUrl in the message and the original error as cause.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 10044d3e-d59c-45ea-b412-0a97784bd76d

📥 Commits

Reviewing files that changed from the base of the PR and between f9523d5 and e918497.

📒 Files selected for processing (1)
  • website/scripts/sync-algolia-crawler.mjs

Comment thread website/scripts/sync-algolia-crawler.mjs Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

Suppressed comments (3)

website/scripts/sync-algolia-crawler.mjs:158

  • This comment says 429 is "worth retrying", but the code does not retry; it just warns and skips verification. Either add a retry loop or adjust the comment so behavior and documentation match.
   * A 4xx means this request is wrong — bad URL, or credentials that PATCH but
   * cannot read — rather than the service being unwell. Warning through it is
   * how the previous endpoint stayed broken for three runs, so fail instead.
   * 429 is the exception: that one is worth retrying, not diagnosing.
   */

website/scripts/sync-algolia-crawler.mjs:180

  • If the read-back endpoint returns 200 but omits config (e.g. withConfig not honored), we currently fall back to diffing against the crawler object, which tends to produce a misleading "stored something different" error. Fail explicitly when no config is returned so the failure points to the real problem.
    const payload = await readBack.json();
    // The crawler may arrive wrapped, and its config as a JSON string.
    const crawler = payload.data ?? payload;
    let stored;
    try {

website/scripts/sync-algolia-crawler.mjs:168

  • The 4xx failure path drops the response body, which makes diagnosing 401/403/404 errors harder (especially when the API includes a useful message). Include the response text in the thrown error before failing.
  if (
    readBack &&
    readBack.status >= 400 &&
    readBack.status < 500 &&
    readBack.status !== 429
  ) {
    throw new Error(
      `Read-back failed (${readBack.status}) for ${readBackUrl}; verification cannot run.`,
    );
  }

`readBack.json()` sat outside the try, so a response body that is not
JSON at all — a proxy error page, say — still threw a bare SyntaxError
naming nothing. The previous stub run missed it because it returned a
valid envelope wrapping an invalid config string, exercising only the
inner parse.

Both parses now share one boundary, and the stub suite covers a non-JSON
body as well as a config returned unwrapped, so verification holds
whichever shape the API responds with.
Copilot AI review requested due to automatic review settings August 6, 2026 13:49

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

Suppressed comments (3)

website/scripts/sync-algolia-crawler.mjs:179

  • stored falls back to the entire crawler object when crawler.config is missing. If the API returns a crawler payload without config (e.g., due to permissions or withConfig being ignored), the diff will compare against the wrong shape and fail with a misleading “stored something different” message. It’s better to explicitly detect a crawler payload missing config and fail with a clear error that verification cannot run.
      const crawler = payload.data ?? payload;
      stored =
        typeof crawler.config === 'string'
          ? JSON.parse(crawler.config)
          : (crawler.config ?? crawler);

website/scripts/sync-algolia-crawler.mjs:158

  • The comment says 429 “is worth retrying”, but the code doesn’t retry; it only skips verification. Either implement a retry/backoff, or update the comment to match the current behavior to avoid confusion during incident/debugging.
   * A 4xx means this request is wrong — bad URL, or credentials that PATCH but
   * cannot read — rather than the service being unwell. Warning through it is
   * how the previous endpoint stayed broken for three runs, so fail instead.
   * 429 is the exception: that one is worth retrying, not diagnosing.
   */

website/scripts/sync-algolia-crawler.mjs:149

  • In the fetch catch handler, error isn’t guaranteed to be an Error instance. Accessing error.message can produce undefined (or throw if something non-object is thrown), which makes logs less useful. Converting to a safe string avoids that.
    console.warn(`Could not reach ${readBackUrl} (${error.message}).`);

Two independent reviews found the verification could still pass while the
stored config differed, including in the one way it exists to catch.

- `unwrapFunctions` collapsed `{__type:'function', source}` to the bare
  source string on both sides, so an extractor stored as a plain string —
  which never executes, and whose only symptom is an empty index — compared
  equal. It was added to avoid a false failure that cannot happen: the API
  rejects bare strings outright. Removed; envelopes now compare structurally,
  which also stops sibling keys such as a disabling flag being discarded.

- The diff ran over `Object.keys(sent)`, so anything present only in the
  stored config was invisible: a setting hand-added in the dashboard, or a
  key deleted from this file, which a partial update leaves in place. It now
  diffs the union, ignoring the server-owned `apiKey`.

- Transport failures, 429 and 5xx warned and exited 0. A permanent mistake —
  wrong host, a key that can write but not read — is indistinguishable from a
  blip, so that path could stay green forever; the same shape as the 404 that
  went unnoticed for three runs. Now retried twice, then failed. Nothing
  reaches the end without either verifying or failing.

- A response without `config` was compared against the crawler object and
  reported as drift in every field. It now says so plainly.

- The `cause` chain was attached but never printed, so failures lost their
  reason. Print the error itself; no error here carries credentials.

Ten scenarios exercised against a stubbed API: match, wrapped envelope and
transient 5xx pass; stale stored key, bare extractor, envelope flag, missing
config, 403, persistent 429 and DNS failure all fail. Credential scan across
those paths finds nothing.
Copilot AI review requested due to automatic review settings August 6, 2026 14:04

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

Suppressed comments (2)

website/scripts/sync-algolia-crawler.mjs:127

  • When retrying after a non-OK response, the response body should be cancelled before sleeping/retrying to avoid keeping the underlying connection open unnecessarily.
    await sleep(retryDelaysMs[attempt]);

website/scripts/sync-algolia-crawler.mjs:90

  • The PR description says transient read-back failures should warn without failing, but readWithRetries currently throws on network errors (after retries) and on 429/5xx once retries are exhausted, which will fail the job instead of skipping verification. Please align either the implementation (warn + skip verification for transient failures) or the PR description / doc comment here so CI behavior matches the intended policy.
 *
 * Nothing here warns and carries on: a permanent mistake — a wrong host, a key
 * that can write but not read — would otherwise look exactly like a blip and
 * leave the job green with no verification, which is how the previous endpoint
 * stayed broken for three runs.

@fb55
fb55 merged commit d3bf4b7 into main Aug 7, 2026
18 checks passed
@fb55
fb55 deleted the fix/crawler-readback branch August 7, 2026 22:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants