From ac8438420f898765bd3bea908fddede58ab21cfe Mon Sep 17 00:00:00 2001 From: Mike Odnis Date: Fri, 25 Sep 2026 04:39:00 -0400 Subject: [PATCH 1/4] fix(ci): exclude x.com from lychee instead of deleting the social link The weekly lychee run has failed on 2026-09-14 and 2026-09-21 with exactly one error: [403] https://x.com/resqsystems_inc (docs.json:9633) | Forbidden x.com serves 403 to every non-browser client, so this is a false positive: the link is correct and works for readers. It was added deliberately in 31b1c25 ("update footer social handles"). Excluded by host rather than adding 403 to --accept, which would apply globally and hide genuinely forbidden links everywhere else. The comment explaining this is deliberately placed above `uses:` and not inside the `args:` block. `args` is a folded block scalar, so its contents are literal and '#' does not start a comment there -- a note written inside it is passed to lychee as arguments. Verified by parsing the workflow: the resulting args string contains no '#'. Verified with lychee 0.24.2 against docs.json: the x.com URL moves from checked to excluded, and no other link changes classification. This supersedes #131, which proposed deleting the x.com entry from docs.json. That would have removed the company's social link from the published footer to satisfy a checker false-positive. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/lychee.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/lychee.yml b/.github/workflows/lychee.yml index 36641ab9..c8c35032 100644 --- a/.github/workflows/lychee.yml +++ b/.github/workflows/lychee.yml @@ -37,6 +37,14 @@ jobs: restore-keys: cache-lychee- - name: Run lychee + # `args` is a folded block scalar: everything inside it is literal, + # so '#' does NOT start a comment there and would be passed to + # lychee as an argument. Keep explanatory notes out here. + # + # --exclude ^https://x\.com/ : x.com serves 403 to every non-browser + # client, so the footer social link fails the check while working + # fine for readers. Excluded by host rather than accepting 403 + # globally, which would hide genuinely forbidden links elsewhere. uses: lycheeverse/lychee-action@e7477775783ea5526144ba13e8db5eec57747ce8 # v2 with: args: >- @@ -46,6 +54,7 @@ jobs: --root-dir ${{ github.workspace }} --scheme http --scheme https + --exclude ^https://x\.com/ --accept 200,204,206,429 --max-retries 2 --retry-wait-time 5 From 8af375fcb7eef94f5c10666d5268706fa5f3f661 Mon Sep 17 00:00:00 2001 From: Mike Odnis Date: Fri, 25 Sep 2026 04:56:41 -0400 Subject: [PATCH 2/4] fix(ci): throttle lychee so github.com stops returning 504 Dispatching lychee on this branch confirmed the x.com exclusion works (that URL moves to excluded) but the run still failed, with 8 errors that were not present in the 2026-09-21 scheduled run: [504] github.com/resq-software/npm/blob/a23b0e8.../file.ts#L121 ... and 7 more deep links into the same file All 8 are 504 Gateway Timeout, all github.com, and all return 200 when fetched directly. They are throttling, not broken links. The cause is volume: 2118 of the ~2984 external links in this repo point at github.com, and lychee's default concurrency is 128. That is enough parallel load on one host to provoke gateway timeouts, which is why the same links pass in one run and fail in the next. Lowering concurrency to 24 and retrying more patiently (4 attempts, 10s apart) treats the cause. Adding 504 to --accept would have been the smaller diff but would hide genuine gateway failures across every host. This makes the weekly run slower, which is an acceptable trade for a scheduled non-blocking job. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/lychee.yml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lychee.yml b/.github/workflows/lychee.yml index c8c35032..f745a9f9 100644 --- a/.github/workflows/lychee.yml +++ b/.github/workflows/lychee.yml @@ -45,6 +45,13 @@ jobs: # client, so the footer social link fails the check while working # fine for readers. Excluded by host rather than accepting 403 # globally, which would hide genuinely forbidden links elsewhere. + # + # --max-concurrency / --max-retries: 2118 of the ~2984 external + # links point at github.com, and lychee's default concurrency (128) + # provokes 504s from it. Those are throttling, not broken links -- + # the same URLs return 200 when fetched directly. Going slower and + # retrying longer fixes the cause; adding 504 to --accept would + # instead hide real gateway failures everywhere. uses: lycheeverse/lychee-action@e7477775783ea5526144ba13e8db5eec57747ce8 # v2 with: args: >- @@ -56,8 +63,9 @@ jobs: --scheme https --exclude ^https://x\.com/ --accept 200,204,206,429 - --max-retries 2 - --retry-wait-time 5 + --max-concurrency 24 + --max-retries 4 + --retry-wait-time 10 './**/*.md' './**/*.mdx' './docs.json' From 00f483e0db2ae55176b5888c41c89320f54973ee Mon Sep 17 00:00:00 2001 From: Mike Odnis Date: Fri, 25 Sep 2026 05:04:14 -0400 Subject: [PATCH 3/4] fix(ci): give lychee a GitHub token so github.com stops rate-limiting it Throttling to concurrency 24 took the run from 8 errors to 1, but the last one is the same class: [503] github.com/resq-software/npm/blob/a23b0e8.../memoize.fn.ts#L85 Lowering concurrency further would trade a lot of wall-clock for a result that is still non-deterministic, because the underlying problem is that 2118 of the ~2984 external links are github.com and lychee was fetching every one of them as anonymous HTML. With GITHUB_TOKEN set, lychee resolves github.com links through the GitHub API instead. That raises the rate limit substantially and skips the HTML fetch, which is the thing being throttled. The token is the default read-only workflow token; `permissions` stays at `contents: read`, and every repository linked from these docs is public, so no extra access is granted. Concurrency stays at 24. It is no longer load-bearing for github.com but still keeps the other ~870 links polite. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/lychee.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/lychee.yml b/.github/workflows/lychee.yml index f745a9f9..49bb06e9 100644 --- a/.github/workflows/lychee.yml +++ b/.github/workflows/lychee.yml @@ -53,6 +53,13 @@ jobs: # retrying longer fixes the cause; adding 504 to --accept would # instead hide real gateway failures everywhere. uses: lycheeverse/lychee-action@e7477775783ea5526144ba13e8db5eec57747ce8 # v2 + env: + # 2118 of the ~2984 external links are github.com. Unauthenticated, + # lychee scrapes them as HTML and gets rate-limited into 503/504s. + # With a token it uses the GitHub API instead, which both raises the + # limit and avoids the HTML fetch entirely. Read-only, and every + # linked repo here is public. + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: args: >- --cache From 1cc4febdb441791ed62877ee8bdbb3b6fd6d40e0 Mon Sep 17 00:00:00 2001 From: Mike Odnis Date: Fri, 25 Sep 2026 06:17:56 -0400 Subject: [PATCH 4/4] fix(ci): quote the lychee exclude regex so the shell stops eating the escape lychee-action's entrypoint ends in eval lychee ${CHECKBOX} ${FORMAT} --output ${LYCHEE_TMP} ${ARGS} so the argument string is re-parsed by the shell. An unquoted \. does not survive that: lychee was receiving ^https://x.com/ with . as a regex wildcard, which would also exclude hosts like xNcom. Confirmed by replaying the action's eval against both forms: --exclude ^https://x\.com/ -> lychee sees ^https://x.com/ --exclude '^https://x\.com/' -> lychee sees ^https://x\.com/ The behaviour was not visible in the green run because both patterns match x.com; only the blast radius differs. Reported by CodeRabbit on #137. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/lychee.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lychee.yml b/.github/workflows/lychee.yml index 49bb06e9..aab9e990 100644 --- a/.github/workflows/lychee.yml +++ b/.github/workflows/lychee.yml @@ -41,10 +41,13 @@ jobs: # so '#' does NOT start a comment there and would be passed to # lychee as an argument. Keep explanatory notes out here. # - # --exclude ^https://x\.com/ : x.com serves 403 to every non-browser + # --exclude '^https://x\.com/' : x.com serves 403 to every non-browser # client, so the footer social link fails the check while working # fine for readers. Excluded by host rather than accepting 403 # globally, which would hide genuinely forbidden links elsewhere. + # The single quotes are load-bearing: lychee-action's entrypoint runs + # `eval lychee ... ${ARGS}`, so an unquoted \. is eaten by the shell + # and lychee would receive ^https://x.com/ with . as a wildcard. # # --max-concurrency / --max-retries: 2118 of the ~2984 external # links point at github.com, and lychee's default concurrency (128) @@ -68,7 +71,7 @@ jobs: --root-dir ${{ github.workspace }} --scheme http --scheme https - --exclude ^https://x\.com/ + --exclude '^https://x\.com/' --accept 200,204,206,429 --max-concurrency 24 --max-retries 4