Skip to content

feat(cache): prevent bots from writing to cache#1128

Open
vibegui wants to merge 3 commits intomainfrom
feat/cache-bot-write-guard
Open

feat(cache): prevent bots from writing to cache#1128
vibegui wants to merge 3 commits intomainfrom
feat/cache-bot-write-guard

Conversation

@vibegui
Copy link
Copy Markdown
Contributor

@vibegui vibegui commented Mar 18, 2026

Summary

  • Bots can read from cache but must not write or trigger background revalidation
  • Bots often hit arbitrary URLs with unique query params that would pollute all cache tiers with one-hit entries
  • Uses existing isBot() utility (UA-based detection)
  • Stale responses are still served to bots (read-only, no revalidation triggered)

Test plan

  • Send request with bot UA — verify cache hit/stale works but no new entries are written
  • Send request with normal UA — verify cache write works as before
  • Monitor loader_cache metric — bot requests should show as hits/stale but never miss→write

🤖 Generated with Claude Code

PR 5 of 5 — split from #1122. Merge order: 1 → 2 → 3 → 4 → 5


Summary by cubic

Prevent bots from writing to the loader cache, triggering background revalidation, or leading non-bot singleFlight work. Bots can still read cached/stale responses and now deduplicate via a separate singleFlight key.

  • New Features
    • Detect bots via isBot (User-Agent).
    • Skip cache.put and background revalidation for bots.
    • Use a separate singleFlight key for bot requests to dedupe bot traffic without affecting non-bot callers.
    • No behavior changes for normal users.

Written for commit 844cac8. Summary will update on new commits.

Summary by CodeRabbit

  • Bug Fixes
    • Prevented automated/bot traffic from triggering cache writes and background revalidations, reducing redundant processing and load.
    • Bots can still read cached content to ensure consistent responses.
    • Bot requests are deduplicated separately from regular traffic to avoid interfering with normal cache behavior.

…ation

Bots can read from cache but must not write to it or trigger background
revalidation. They often hit arbitrary URLs with unique query params
that would pollute all cache tiers with one-hit entries.

- Detect bot requests via User-Agent (existing isBot utility)
- Skip cache.put() for bot requests
- Skip background revalidation for bot requests
- Bots still get served stale/cached responses (read-only)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

Tagging Options

Should a new tag be published when this PR is merged?

  • 👍 for Patch 1.178.1 update
  • 🎉 for Minor 1.179.0 update
  • 🚀 for Major 2.0.0 update

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 18, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 59d0723d-f907-4338-af95-7ce9b05c7c38

📥 Commits

Reviewing files that changed from the base of the PR and between b34270d and 844cac8.

📒 Files selected for processing (1)
  • blocks/loader.ts

📝 Walkthrough

Walkthrough

Loader now detects bot requests and treats them as cache-read-only: bots may read cached responses but are prevented from performing cache.put, spawning background revalidation, or updating flight deduplication for non-bot traffic. No public APIs were changed. (44 words)

Changes

Cohort / File(s) Summary
Bot-aware caching
blocks/loader.ts
Adds isBot detection and isBotRequest gating. Bots can read cache but are prevented from calling cache.put, spawning background revalidation (stale revalidate), and are assigned a bot-scoped flight key (bot:<url>) to dedupe among bots. Preserves existing hit/miss/stale control flow for non-bot requests.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Client
    participant Loader
    participant Cache
    participant BackgroundReval

    Client->>Loader: HTTP Request
    Loader->>Loader: isBot(request)?
    alt Bot request
        Loader->>Cache: read
        Cache-->>Loader: cached (fresh/stale/miss)
        alt cached
            Loader-->>Client: serve cached (no cache.put)
        else miss
            Loader-->>Client: serve generated (no background reval)
        end
    else Non-bot request
        Loader->>Cache: read
        Cache-->>Loader: cached (fresh/stale/miss)
        alt fresh
            Loader-->>Client: serve fresh
        else miss or stale
            Loader->>BackgroundReval: spawn revalidation (background)
            BackgroundReval->>Cache: cache.put (update)
            BackgroundReval-->>Loader: done
            Loader-->>Client: serve content
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hop through code with careful paws,
Bots may peek but must pause,
No writes, no reval for their trail,
The cache stays neat along my trail,
A twitch, a hop — the loader sings, huzzah!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(cache): prevent bots from writing to cache' clearly and specifically describes the main objective of the changeset: preventing bots from writing to the cache while still allowing reads.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 feat/cache-bot-write-guard
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 1 file

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

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 the current code and only fix it if needed.

Inline comments:
In `@blocks/loader.ts`:
- Around line 313-326: The single-flight leader selection uses request.url
alone, allowing a bot request to become leader and cause concurrent non-bot
callers to inherit bot behavior via the closure-captured isBotRequest; fix by
making the flight key include the bot flag and by evaluating isBotRequest into a
local variable before creating the flight so the leader decision is
per-client-type (e.g., build a flightKey using request.url plus isBotRequest or
use separate flight maps for bots vs non-bots), and keep cache.put and
revalidation guarded by that local isBotRequest value so non-bot requests never
inherit bot-read-only behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 70da6172-d261-429a-8c7b-4045782dc816

📥 Commits

Reviewing files that changed from the base of the PR and between f8d4b09 and 6093d79.

📒 Files selected for processing (1)
  • blocks/loader.ts

vibegui and others added 2 commits March 18, 2026 11:47
Bot requests skip cache writes and revalidation. If a bot became the
singleFlight leader, concurrent non-bot callers would inherit that
behavior and miss their cache write. Fix: bots bypass singleFlight
entirely and run staleWhileRevalidate directly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Instead of bypassing singleFlight entirely (which wastes CPU on duplicate
bot requests), use a prefixed flight key so bots still deduplicate among
themselves but never become leader for non-bot callers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.

1 participant