{
  "id": 7431565,
  "title": "A Tiny Nim Microservice, Three Real Bugs, and What They Taught Me About My Own Mummy Fork",
  "url": "https://urgent.news/2026/09/15/a-tiny-nim-microservice-three-real-bugs-and-what-they-taught-me-about",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-09-15T00:12:26.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/isaiahpeter/a-tiny-nim-microservice-three-real-bugs-and-what-they-taught-me-about-my-own-mummy-fork-2b51"
  },
  "original_language": "en",
  "account": "A Tiny Nim Microservice, Three Real Bugs, and What They Taught Me About My Own Mummy Fork\n\nI recently built a simple POST /api/contact endpoint on my personal website for receiving messages. I chose to develop it directly on my own Mummy fork, which offers features like OpenAPI schema generation, typed validation, and composable middleware. I assumed this would be a trivial task, but three significant bugs I encountered along the way taught me more about the fork's internal workings than the development process itself.\n\nThe service structure was straightforward. It had a ContactBody type with required name, email, and message fields. Validation occurred in two layers - the first checked presence and types against the schema generated by Mummy, while the second enforced non-empty fields, character limits, and a custom email format check. Any ValidationError raised during validation was converted to a clean 400 response by installDefaultErrorHandler. The service also included CORS middleware, an in-memory rate limiter, and logging middleware. The OpenAPI documentation was generated automatically from the validation schema.\n\nHowever, deploying to Render's free tier revealed unexpected issues. I initially used std/smtp for sending emails, but it failed to send messages due to Render blocking outbound SMTP ports. Switching to Resend's REST API resolved the issue, as it uses HTTPS and returns ordinary HTTP errors for failures. This experience highlighted the importance of discovering real-world constraints during deployment, rather than just reading documentation.\n\nDuring development, I encountered three bugs that taught me more about Mummy's internals than building the feature itself:\n\n1. Two seemingly identical HttpHeaders types existed, but were actually different. Nim's module system treats distinct alias imports as separate types, leading to type mismatches. Importing std/httpcore except for HttpHeaders fixed the issue, demonstrating that even structurally similar types can have different identities.\n\n2. The compiler's gcsafe attribute was strict about mutable globals accessed within gcsafe contexts, even if the global appeared to be immutable. My CORS middleware attempted to read a global holding allowed origins, which triggered a gcsafe error. Using a cast to gcsafe around the specific read resolved the error, teaching me that \"never mutated after startup\" is different from \"thread-safe\" in the compiler's checks.\n\n3. An unregistered route prevented middleware from running, including for requests that needed it. Mummy only runs middleware for registered methods, so a missing OPTIONS preflight route caused CORS middleware to fail, blocking client-side requests. Adding a dummy OPTIONS route let middleware handle the request properly, showing that even seemingly simple issues can have far-reaching impacts.\n\nTo ensure the endpoint was robust, I tested various edge cases: disallowed origins, malformed emails, name length boundaries, rapid submissions from the same IP, and health checks. This thorough testing verified the service's resilience and prepared it for production use. Overall, building this tiny microservice taught me valuable lessons about Nim's module system, data races, and middleware registration that went beyond the initial feature requirements.",
  "summary": "A Tiny Nim Microservice, Three Real Bugs, and What They Taught Me About My Own Mummy Fork I recently needed something small: a POST /api/contact endpoint for my portfolio site at https://www.isaiah.name.ng that takes a name, email, and message, validates it, and emails it to me. The kind of thing you'd normally knock out without thinking twice. I decided to build it directly on my own Mummy fork…",
  "key_points": [],
  "editors_take": null,
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}