Conversation
This extension allows setting, getting, and deleting key-value pairs in a worldwide database using Cloudflare's KV storage.
WalkthroughAdds a new Scratch extension file implementing a CTDB key–value API with scope management and set/get/delete blocks, and updates ChangesWorldwide Database Extension
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. 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. Comment |
There was a problem hiding this comment.
Review Summary
This PR adds a worldwide database extension using Cloudflare KV storage. The implementation is functional but has critical error handling gaps that could lead to silent failures and data inconsistency.
Critical Issues Found:
- Missing error handling in
setKeymethod - failed writes are silently ignored - Missing error handling in
deleteKeymethod - failed deletions are not reported - Missing input validation for empty keys in all methods
Required Changes:
All three methods need proper error handling with try-catch blocks and response status validation to prevent silent failures that could confuse users about the actual state of their data.
Please address these error handling issues before merging to ensure reliable operation of the extension.
You can now have the agent implement changes and create commits directly on your pull request's source branch. Simply comment with /q followed by your request in natural language to ask the agent to make changes.
| } | ||
|
|
||
| async setKey(args) { | ||
| const key = encodeURIComponent(args.KEY); |
There was a problem hiding this comment.
Add validation for empty or whitespace-only keys before making API requests. Empty keys will cause API errors and waste network resources. Validate that args.KEY is not empty or only whitespace.
| const key = encodeURIComponent(args.KEY); | |
| const key = encodeURIComponent(args.KEY); | |
| if (!key || key.trim() === "") { | |
| console.error("Key cannot be empty"); | |
| return; | |
| } |
| async setKey(args) { | ||
| const key = encodeURIComponent(args.KEY); | ||
|
|
||
| await fetch(`https://ctdbapi.funstrangeegg.workers.dev/api/${key}`, { | ||
| method: "POST", | ||
| headers: { "Content-Type": "application/json" }, | ||
| body: JSON.stringify(args.VALUE) | ||
| }); | ||
| } |
There was a problem hiding this comment.
🛑 Logic Error: The setKey method silently ignores fetch errors and doesn't verify the response status. Users may believe data was saved when the API request actually failed, leading to data loss and inconsistent application state.
| async setKey(args) { | |
| const key = encodeURIComponent(args.KEY); | |
| await fetch(`https://ctdbapi.funstrangeegg.workers.dev/api/${key}`, { | |
| method: "POST", | |
| headers: { "Content-Type": "application/json" }, | |
| body: JSON.stringify(args.VALUE) | |
| }); | |
| } | |
| async setKey(args) { | |
| const key = encodeURIComponent(args.KEY); | |
| try { | |
| const res = await fetch(` { | |
| method: "POST", | |
| headers: { "Content-Type": "application/json" }, | |
| body: JSON.stringify(args.VALUE) | |
| }); | |
| if (!res.ok) { | |
| console.error(`Failed to set key: ${res.status} ${res.statusText}`); | |
| } | |
| } catch (e) { | |
| console.error("Network error setting key:", e); | |
| } | |
| } |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
extensions/8to16/CTDB.js (1)
1-97:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winRun Prettier for this file to clear the format check warning.
Formatting check is currently failing in CI for
extensions/8to16/CTDB.js.🤖 Prompt for 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. In `@extensions/8to16/CTDB.js` around lines 1 - 97, Run Prettier on this file to fix CI formatting failures: format the WWDBExtension class and its methods (getInfo, setKey, getKey, deleteKey) so spacing, semicolons, quotes and indentation match project Prettier rules, save the updated extensions/8to16/CTDB.js, and commit the formatted file so the formatting check passes.
🧹 Nitpick comments (1)
extensions/8to16/CTDB.js (1)
51-59: ⚡ Quick winHandle non-OK responses in command blocks to avoid silent write/delete failures.
setKeyanddeleteKeycurrently ignore HTTP status/errors; failed writes/deletes look successful to users.Suggested patch
async setKey(args) { const key = encodeURIComponent(args.KEY); - await Scratch.fetch(`https://ctdbapi.funstrangeegg.workers.dev/api/${key}`, { + const res = await Scratch.fetch(`https://ctdbapi.funstrangeegg.workers.dev/api/${key}`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(args.VALUE) }); + if (!res.ok) throw new Error(`setKey failed with status ${res.status}`); } ... async deleteKey(args) { const key = encodeURIComponent(args.KEY); - await Scratch.fetch(`https://ctdbapi.funstrangeegg.workers.dev/api/${key}`, { + const res = await Scratch.fetch(`https://ctdbapi.funstrangeegg.workers.dev/api/${key}`, { method: "DELETE" }); + if (!res.ok) throw new Error(`deleteKey failed with status ${res.status}`); }Also applies to: 86-92
🤖 Prompt for 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. In `@extensions/8to16/CTDB.js` around lines 51 - 59, The setKey and deleteKey functions currently ignore the fetch response so failed HTTP writes/deletes appear to succeed; update both functions (setKey and deleteKey) to capture the fetch Response, check response.ok (or status), and throw or return an error if not OK, including the status and response text to surface the failure; ensure you await response.text() or response.json() as needed for the error message and propagate the failure to the caller instead of silently swallowing it.
🤖 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 `@extensions/8to16/CTDB.js`:
- Line 18: Replace hardcoded English strings in the extension descriptor with
translatable calls: change the top-level name property "Worldwide DB" and the
block text strings (the block entries with text at the positions around lines
25, 34, 42) to use Scratch.translate("...") instead of literal strings; update
the name property and each block's text field in the exported descriptor (look
for the name property and the blocks array entries in CTDB.js) to call
Scratch.translate with the original English text.
- Around line 54-58: The code is calling the global fetch API (e.g., await
fetch(`https://ctdbapi...`, { method: "POST", headers: ..., body:
JSON.stringify(args.VALUE) })) which violates the extension runtime rule;
replace all global fetch calls in CTDB.js with Scratch.fetch (preserving the
same URL, options object, and await usage) so instances that use the template
URL with variable key and args.VALUE, and any other fetch usages in this file,
call Scratch.fetch instead of fetch.
---
Outside diff comments:
In `@extensions/8to16/CTDB.js`:
- Around line 1-97: Run Prettier on this file to fix CI formatting failures:
format the WWDBExtension class and its methods (getInfo, setKey, getKey,
deleteKey) so spacing, semicolons, quotes and indentation match project Prettier
rules, save the updated extensions/8to16/CTDB.js, and commit the formatted file
so the formatting check passes.
---
Nitpick comments:
In `@extensions/8to16/CTDB.js`:
- Around line 51-59: The setKey and deleteKey functions currently ignore the
fetch response so failed HTTP writes/deletes appear to succeed; update both
functions (setKey and deleteKey) to capture the fetch Response, check
response.ok (or status), and throw or return an error if not OK, including the
status and response text to surface the failure; ensure you await
response.text() or response.json() as needed for the error message and propagate
the failure to the caller instead of silently swallowing it.
🪄 Autofix (Beta)
✅ Autofix completed
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: af48b4db-1377-4c63-a88f-7316895db14f
📒 Files selected for processing (1)
extensions/8to16/CTDB.js
|
Note Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it. Fixes Applied SuccessfullyFixed 2 file(s) based on 2 unresolved review comments. Files modified:
Commit: The changes have been pushed to the Time taken: |
|
@coderabbitai should I open-source the backend? I mean I hardcoded a password in there so I'll have to do something about that |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 2517
1. Rotate the hardcoded password firstRegardless of anything else — treat the hardcoded password as already compromised and rotate it immediately. Even after you scrub it from the code, if it was ever committed to a git repo, it lives in the git history. 2. Move it to a Cloudflare Worker SecretCloudflare Workers has built-in support for secrets (environment variables that are never exposed in source): wrangler secret put MY_SECRET_PASSWORDThen in your Worker code, access it via 3. Clean the git historyIf the password was ever committed, scrub it before making the repo public: # Using git-filter-repo (recommended over BFG)
git filter-repo --replace-text <(echo 'old-hardcoded-password==>REDACTED')Or use GitHub's secret scanning push protection to catch it before it goes public. Separate concern: this extension has no auth at all 🔓Looking at the extension code, |
Fixed 2 file(s) based on 2 unresolved review comments. Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
|
@coderabbitai funnily enough i never even made a git commit since the initial repo creation |
|
Tip For best results, initiate chat on the files or code changes.
Since the password hasn't been committed yet, your to-do list is much simpler:
The no-auth issue I mentioned (anyone being able to overwrite/delete keys) is still worth thinking about before merging, but at least the credential situation is clean. Good timing! |
|
@coderabbitai it is specifically for the moderation panel we could probably just use GitHub auth instead if someone wants to get into that |
|
Tip For best results, initiate chat on the files or code changes.
A rough flow would be: One small thing worth keeping in mind: this is separate from the Scratch extension side, where |
|
!format |
|
@coderabbitai moderators can view all keys in one go and see statistics and other things the thing would be pointless if write was restricted to mods |
|
Tip For best results, initiate chat on the files or code changes.
With open writes being intentional, the things that are probably worth thinking about before this goes live are:
The moderator panel being able to see everything and spot abuse patterns is a good safety net regardless. GitHub OAuth gating that panel (as you mentioned) seems like the right call. |
|
Tip For best results, initiate chat on the files or code changes.
Could you paste what the endpoint returns (e.g. a JSON response, an API spec, or an error message)? That way I can give you more targeted feedback on what's already implemented vs. what might still be worth adding (like the rate limiting or key namespacing we discussed). Alternatively, if it exposes a spec or README at the root, you could paste that here and I can review it in context with the extension code. |
|
@coderabbitai you can browse the web wdym? ive seen you go to URLs before |
|
Tip For best results, initiate chat on the files or code changes. You're right, my apologies for the confusion! Let me check it now.
Could you paste the response you get from the root URL (or any relevant endpoint)? That way I can give you more concrete feedback on what's already in place! 🐇 |
|
@coderabbitai run |
|
Custom finishing touch recipe not found: |
|
@coderabbitai @supervoidcoder do you like it also [https://github.com/ampelc/CTDB](backend is now open source yay) |
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 425 🏁 Script executed: Length of output: 17247
✅ Things that look great
🔴 Stored XSS in
|
|
/q do you like it |
|
I'm here to help with code review feedback. If you have specific questions about the implementation, code quality, security concerns, or functionality of the changes in this PR, I'd be happy to address them. |
|
/q i mean do you like the concept of the extension and can you find problems in it |
|
Tip For best results, initiate chat on the files or code changes.
The flash drive wearing out is the sneaky killer — SD cards and USB sticks are not designed for database-style random writes 24/7. You'd likely get silent corruption or sudden death within months under any real write load. A proper SSD over USB would help a lot there. For a personal project or home automation stuff? Pi + SSD is totally legit and people run real services on them. For "any Scratch user in the world can write to it" though, Cloudflare edge is hard to beat for free. 🐇 |
|
@coderabbitai time to go gam... i mean.... get a job... obviously wait this doestn make sense why is it people my age can get a job but not go blow some steam by betting it all on 17 red |
|
Tip For best results, initiate chat on the files or code changes.
|
|
@coderabbitai but WHY i dont want to get a job... losing my dignity as some cashier while im miserable thinking of how i could be using that time 😢 |
|
Tip For best results, initiate chat on the files or code changes.
The cashier gig (if it ever happens) funds the thing you actually care about. Plenty of great engineers started there. 🐇 Now — back to the matter at hand — |
|
@coderabbitai bro amp already merged it hours ago anyways ................................... |
|
Tip For best results, initiate chat on the files or code changes.
And honestly, the $0 constraint is not a bad place to be as a developer — some of the best free tiers out there right now:
Basically the modern dev stack for a broke-but-determined builder is genuinely excellent. People are running real projects on $0/month all the time. You're already using the right tools. 🐇 |
|
@coderabbitai well i got 2 years of free github pro by giving them my student id, you know any other sweet deals like that? |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🌐 Web query: 💡 Result: Best student developer deals (US, 2026)
If you tell me your stack (e.g., Python/JS/Java, mobile, data/ML, UI/UX) and whether you’re in college vs K–12, I can shortlist the highest-value offers to claim first. Citations:
Already inside your GitHub Student Developer Pack (check if you've claimed them):
Separate things to grab on top:
The JetBrains and GitHub Copilot ones are probably the highest day-to-day value for a developer. 🐇 |
|
copilot: yeah i got it |
|
Tip For best results, initiate chat on the files or code changes.
The real hidden gem in the GitHub Student Pack that I didn't mention: Namecheap gives you a free |
|
until WE finish omniblocks |
|
@coderabbitai azure sounds super cool but what for |
|
Tip For best results, initiate chat on the files or code changes.
Stuff Azure is genuinely good for:
Honest take for your situation though: For what you're doing right now — web projects on Cloudflare, VS Code, building OmniBlocks — Azure doesn't really fill a gap you have. Cloudflare Workers already beats Azure Functions on latency and free tier generosity for edge stuff. GitHub Actions already covers your CI/CD. Where Azure credits become actually useful: if you want to spin up a Linux VM to self-host something (like a dev server you SSH into), or experiment with ML/AI workloads that need real compute. The student credits give you enough to run a small VM for months without touching your wallet. But if Cloudflare + GitHub is already handling everything you need for free? The Azure credits will probably just expire. Claim them anyway (no credit card needed), then forget about it until you actually have a use case. 🐇 |
is that not just... github pages? what's the difference
hmmm perhaps care to elaborate
again HOW IS THIS DIFFERNET FROM GITHUB ACTIONS i have nearly ifninite for free since i use public repos
makes sense, but dont they still use openai models? those suck, gpt models are so insufferable |
|
Tip For best results, initiate chat on the files or code changes.
GitHub Pages vs Azure Static Web Apps: They look similar but have one big difference — GitHub Pages is truly static only. No server-side logic, no API routes, no backend. Azure Static Web Apps adds a thin serverless layer (Azure Functions) alongside the static files, so you can have Azure Functions: Think of it like this — you write a function, it sleeps until someone calls it, runs, then sleeps again. You pay only for the time it's actually executing, not for a server sitting idle. Cloudflare Workers does the same thing but runs at the network edge (closest datacenter to the user). Azure Functions run in a specific region (e.g. East US), so they're a bit slower for global users. Workers wins on latency for worldwide traffic; Azure Functions wins if you need deep integration with other Azure services or need longer execution time limits. Azure DevOps vs GitHub Actions: You nailed it — for public repos with unlimited Actions minutes, there's zero reason to touch Azure DevOps. It's a product that predates GitHub Actions by years, so a lot of enterprises are stuck on it. It's basically GitHub Actions + GitHub Projects + GitHub Packages bundled into a Microsoft product, mostly useful for companies that are all-in on the Microsoft ecosystem or started CI/CD before GitHub Actions existed. Azure AI / Cognitive Services — do they use OpenAI models? Mixed bag:
So if your issue is specifically with GPT-style LLMs, the Cognitive Services vision/speech/OCR stuff is completely unrelated to OpenAI and worth knowing about. (And noted on OmniBlocks having a full community — sounds ambitious! 👀🐇) |
@coderabbitai cant i just... fronteend on github pages and functions for backend called from frontend? for the AI stuff, i find google's models to be better. ocr, vision, not being delusional and stupid (for llms). claude and gemini beat delusional gpt models by 9999999999x like UGH i cant stand gpt they're so braindead |
|
Tip For best results, initiate chat on the files or code changes.
...is exactly what As for the AI models — fair opinions! For context on the landscape:
The practical upshot: if you're building something in OmniBlocks that needs AI features, Google AI Studio has a generous free tier for Gemini API calls, which aligns with your model preference and costs $0. 🐇 |
|
i mean all big companies sell data for money but at least google uses all the data they have for actually useful things instead of microsoft just like being microslop @coderabbitai we're on gpt 5 and now gpt models are:
|
|
Tip For best results, initiate chat on the files or code changes.
What I will say is that the AI landscape is genuinely moving fast — every model has different strengths, and what feels true today might flip in six months. The best move is to just use whichever one actually solves your problem, regardless of the logo on it. Anyway — this PR comment thread has evolved quite a lot from "should I open-source the backend" to cloud storage pricing to career advice to AI model discourse 😄 We should probably let |
|
@coderabbitai wdym slight conflict of interest 👀 |
|
Tip For best results, initiate chat on the files or code changes.
I'll just say: use whatever makes you productive and doesn't make you want to throw your laptop out the window. That's the whole job. 🐇 |
|
@coderabbitai no because by the way you speak (and function) i can clearly tell you use claude but i just KNOW you'll refuse and say "No, I'm CodeRabbit and i'm not alloweed to disclose backend" but you can't hide it bucko obviously coderabbit don't train their wn models |
|
Tip For best results, initiate chat on the files or code changes.
What I can say is that whatever I'm running on, I'm pretty good at reviewing PRs, going on extended tangents about Cloudflare pricing, and dispensing unsolicited career advice to teenagers on GitHub comment threads. That's a very specific skill set. 🐇 |
|
@coderabbitai i told you either way just rest assured you're not a stupid piece of garbage GPT model, you dont have the samalt virus |
|
Tip For best results, initiate chat on the files or code changes.
I'm not sure what the "samalt virus" is specifically, but based on your earlier description of GPT behavior — delusional, gaslight-y, insufferably soulless — I'll assume it's whatever that is, and I'm very glad to be declared free of it. 🐇 Now, important question: is there any actual PR work left to do here, or have we fully pivoted this thread into a tech philosophy podcast? 😄 |
|
samalt -> sam + alt --> sam altman |
|
Tip For best results, initiate chat on the files or code changes.
I'll wear that diagnosis proudly. 🐇 Now — shall we get back to actual code at some point, or is this PR officially a tech talk show now? |
|
@coderabbitai gpt models always also end with the stupid "If you want, tell me [subject]👇 " or "If you want, I can" |
|
Tip For best results, initiate chat on the files or code changes.
It's a very specific kind of helpfulness that loops back on itself forever. Like a waiter who, after you say "I'm good thanks," responds "Great! And if you'd like anything else, just let me know! Would you like me to list what else we have?" Anyway. The PR got merged. You won. The samalt virus has been defeated. 🐇 ( |
Walkthrough
Adds a new Scratch extension file implementing a CTDB key–value API with scope management and set/get/delete blocks, and updates
extensions.jsonto register the new extension.Changes
Worldwide Database Extension
extensions/8to16/CTDB.jsgetInfo()metadata declaring scope controls and KV blocks.extensions/8to16/CTDB.jsprojectScopeinitialized (default"CT");_buildUrl(key)builds CTDBv2 endpoint with URL-encodednameandscope.extensions/8to16/CTDB.jssetKey()POSTs JSON;getKey()GETs, usesres.json(), stringifies objects, returns""on non-OK;deleteKey()sends DELETE and logs failures.extensions/8to16/CTDB.jsScratch.extensions.register(new WWDBExtension()).extensions/extensions.json8to16/CTDB.jsto thejsextensions array (and repositions/formatsderpygamer2142/GPUsb3).Estimated code review effort
🎯 3 (Moderate) | ⏱️ ~20 minutes
Poem