---
title: "Principal Engineer - Benjamin"
description: "A place where I share my thoughts and learnings 💭"
url: "/"
canonical_url: "https://bfzli.com/"
source_url: "https://bfzli.com/index.md"
type: "prose"
updated: "2026-10-09"
---

> Markdown copy of https://bfzli.com/. Append `.md` to any page path on bfzli.com for its markdown twin. Full index: https://bfzli.com/llms.txt

# Hello, I'm Benjamin Fazli

A curious software engineer based in Skopje, North Macedonia, solving engineering problems, building products people use, and sharing what I learn along the way.

## Pages

- [Products](https://bfzli.com/products.md) — Every platform and app, with descriptions
- [Resume](https://bfzli.com/resume.md) — Experience, roles and technical stack

## Recent posts

- [Next.js Server Components Return Stale Data After a Mutation Because the Cache Was Not Invalidated](https://bfzli.com/next-js-server-components-return-stale-data-after-a-mutation-because-the-cache-was-not-invalidated.md) — Fix stale server-rendered data in Next.js after a write operation by revalidating the affected path or tag.
- [Cloudflare Workers Fails to Serve a Custom Domain After the Route Is Missing in wrangler.toml](https://bfzli.com/cloudflare-workers-fails-to-serve-a-custom-domain-after-the-route-is-missing-in-wrangler-toml.md) — Fix a Worker that deploys but never answers traffic on its custom domain because the route binding is absent.
- [Bun Locks a SQLite Database During a Migration and Other Requests Stall](https://bfzli.com/bun-locks-a-sqlite-database-during-a-migration-and-other-requests-stall.md) — Explain why Bun migrations can block SQLite access and how to avoid long exclusive locks.
- [Astro Proxies a Cross-Origin API Request but Drops Cookies and Authorization Headers](https://bfzli.com/astro-proxies-a-cross-origin-api-request-but-drops-cookies-and-authorization-headers.md) — Fix an Astro endpoint that forwards cross-origin requests without preserving credentials or auth headers.
- [Bun Starts a Package Binary but the Command Is Not Found in `node_modules/.bin`](https://bfzli.com/bun-starts-a-package-binary-but-the-command-is-not-found-in-node-modules-bin.md) — Why a Bun-installed CLI fails to launch from a package binary and how to expose the executable correctly.
- [Docker Compose Cannot Resolve a Service Name Because the Container Is on the Wrong Network](https://bfzli.com/docker-compose-cannot-resolve-a-service-name-because-the-container-is-on-the-wrong-network.md) — Why one Compose service cannot reach another by name and how network membership controls DNS resolution.
- [React Native Android Fails with "Duplicate class" During Gradle Compilation](https://bfzli.com/react-native-android-fails-with-duplicate-class-during-gradle-compilation.md) — Why Android builds stop on duplicate classes in React Native and how to identify the conflicting dependency.
- [Nuxt Breaks in the Browser When a Client Component Imports a Server-Only Composable](https://bfzli.com/nuxt-breaks-in-the-browser-when-a-client-component-imports-a-server-only-composable.md) — Why a browser component crashes after importing a composable that touches server-only APIs in Nuxt.
- [Next.js Loads a Self-Hosted Font with FOIT After `next/font` Is Skipped](https://bfzli.com/next-js-loads-a-self-hosted-font-with-foit-after-next-font-is-skipped.md) — How a self-hosted font flashes or swaps late in Next.js when it bypasses `next/font` optimization.
- [Next.js Route Handlers Throw TypeError: Body has already been read After Parsing `request.json()` Twice](https://bfzli.com/next-js-route-handlers-throw-typeerror-body-has-already-been-read-after-parsing-request-json-twice.md) — Why a Next.js route handler fails after the request body is consumed more than once, and how to preserve the stream.
- [Vite Builds Succeed but the Server Serves the Wrong `dist` Folder](https://bfzli.com/vite-builds-succeed-but-the-server-serves-the-wrong-dist-folder.md) — Why a deployment can show an old or empty app after a successful Vite build, and how to point the server at the right output.
- [Bun Publishes a CLI That Runs Without `node_modules/.bin` When the Binary Field Is Wrong](https://bfzli.com/bun-publishes-a-cli-that-runs-without-node-modules-bin-when-the-binary-field-is-wrong.md) — How a Bun package can ship successfully but expose no working command because the bin entry points at the wrong file.
- [Cloudflare Workers Scheduled Triggers Never Run Because the Cron Pattern Is Missing from `wrangler.toml`](https://bfzli.com/cloudflare-workers-scheduled-triggers-never-run-because-the-cron-pattern-is-missing-from-wrangler-toml.md) — Why a Worker deploys successfully but its scheduled job never fires, and how to register the cron trigger correctly.
- [Hono Sends an Empty Response When a Handler Forgets to Return `c.text()`](https://bfzli.com/hono-sends-an-empty-response-when-a-handler-forgets-to-return-c-text.md) — How a Hono route can finish without a body when the handler does not return the response object.
- [Node CLI Fails with ERR_REQUIRE_ESM When `require()` Loads an ESM Dependency](https://bfzli.com/node-cli-fails-with-err-require-esm-when-require-loads-an-esm-dependency.md) — Why a published Node CLI crashes on startup when CommonJS reaches an ESM-only package, and how to fix the import boundary.
- [SvelteKit Tests Throw ReferenceError: window is not defined in JSDOM](https://bfzli.com/sveltekit-tests-throw-referenceerror-window-is-not-defined-in-jsdom.md) — Why browser globals are missing in SvelteKit tests and how to run server-only code under a DOM-aware test environment.
- [Dockerfile Builds a Next.js App, Then Node Crashes with "ERR_OSSL_EVP_UNSUPPORTED"](https://bfzli.com/dockerfile-builds-a-next-js-app-then-node-crashes-with-err-ossl-evp-unsupported.md) — A Docker image with the wrong Node or OpenSSL version can break Next.js builds; align the base image and runtime.
- [Postgres Generates Duplicate IDs After a Manual Import Leaves the Sequence Behind](https://bfzli.com/postgres-generates-duplicate-ids-after-a-manual-import-leaves-the-sequence-behind.md) — Postgres inserts collide when an imported table’s sequence is lower than existing rows; reset the sequence to match the data.
- [Deno Fails a Fetch Call with "Requires net access" in a Worker](https://bfzli.com/deno-fails-a-fetch-call-with-requires-net-access-in-a-worker.md) — Deno blocks outbound requests without the right permission flags or allowlist; grant network access for the target host.
- [Vite Dev Server Fails to Start with "Port 5173 is already in use"](https://bfzli.com/vite-dev-server-fails-to-start-with-port-5173-is-already-in-use.md) — Vite stops before serving when another process already binds the default port; free the port or choose a new one safely.
- [Next.js Route Handler Buffers Server-Sent Events and the Client Never Receives Updates](https://bfzli.com/next-js-route-handler-buffers-server-sent-events-and-the-client-never-receives-updates.md) — Next.js can buffer SSE responses unless the handler returns a streaming response with the right headers and runtime.
- [Nuxt Scheduled Task Never Runs Because Nitro Cron Is Not Registered](https://bfzli.com/nuxt-scheduled-task-never-runs-because-nitro-cron-is-not-registered.md) — Nuxt cron jobs stay silent when Nitro never registers the scheduled route or preset; fix the task registration and deployment target.
- [Cloudflare Pages Build Fails with "require is not defined" After a CommonJS Import](https://bfzli.com/cloudflare-pages-build-fails-with-require-is-not-defined-after-a-commonjs-import.md) — Cloudflare Pages breaks when a build step loads CommonJS code in an ESM-only runtime; fix the module format mismatch.
- [Vite Refuses a CSS Import from `node_modules` with "does not exist under root" During Build](https://bfzli.com/vite-refuses-a-css-import-from-node-modules-with-does-not-exist-under-root-during-build.md) — A production build can fail when a stylesheet import points outside Vite’s project root or references an unsupported path.
- [Docker Cannot Reach Postgres on localhost Because the App Container Resolves Its Own Loopback Interface](https://bfzli.com/docker-cannot-reach-postgres-on-localhost-because-the-app-container-resolves-its-own-loopback-interface.md) — A containerized app fails to connect to `localhost` because `127.0.0.1` points at the container, not the database host.
- [Nuxt Ignores a Client-Only Widget During Static Generation Because the Page Was Rendered at Build Time](https://bfzli.com/nuxt-ignores-a-client-only-widget-during-static-generation-because-the-page-was-rendered-at-build-time.md) — A widget that depends on browser APIs disappears or fails when Nuxt prerenders the page as static HTML.
- [Hono Loses Session Cookies on Cross-Origin Requests Because `fetch` Never Sends Credentials](https://bfzli.com/hono-loses-session-cookies-on-cross-origin-requests-because-fetch-never-sends-credentials.md) — Cookie-based auth fails when browser requests omit credentials or the response omits the correct CORS cookie headers.
- [Express Rejects Stripe Webhooks with a Signature Mismatch When JSON Middleware Consumes the Raw Body](https://bfzli.com/express-rejects-stripe-webhooks-with-a-signature-mismatch-when-json-middleware-consumes-the-raw-body.md) — Stripe signature verification fails when Express parses the request body before you compute the webhook HMAC.
- [React Native Android Fails with "Unable to resolve module" After a Native Package Is Added to the Bundle](https://bfzli.com/react-native-android-fails-with-unable-to-resolve-module-after-a-native-package-is-added-to-the-bundle.md) — A release build can fail when Metro cannot bundle a dependency that imports Node or unlinked native code.
- [SvelteKit Breaks Prerender with "window is not defined" When a Server File Imports Browser Code](https://bfzli.com/sveltekit-breaks-prerender-with-window-is-not-defined-when-a-server-file-imports-browser-code.md) — Prerendered SvelteKit pages crash when server-side code pulls in a browser-only module that touches `window` during build.
- [Nginx Proxies a WebSocket Endpoint but the Client Fails the Upgrade with `400 Bad Request`](https://bfzli.com/nginx-proxies-a-websocket-endpoint-but-the-client-fails-the-upgrade-with-400-bad-request.md) — Fix WebSocket proxying by forwarding the upgrade headers and using the right HTTP version.
- [Docker Compose Starts an API Before Postgres Is Ready and the App Logs `ECONNREFUSED`](https://bfzli.com/docker-compose-starts-an-api-before-postgres-is-ready-and-the-app-logs-econnrefused.md) — Use health checks and dependency conditions so Compose waits for Postgres instead of starting the app too early.
- [Node Imports a Local ESM File as `[ERR_MODULE_NOT_FOUND]` Because the Path Is Not a File URL](https://bfzli.com/node-imports-a-local-esm-file-as-err-module-not-found-because-the-path-is-not-a-file-url.md) — Fix local ESM imports in Node when relative paths or missing extensions stop module resolution.
- [Remix Streams `defer()` Data but the Page Stalls Because No `<Await>` Boundary Wraps It](https://bfzli.com/remix-streams-defer-data-but-the-page-stalls-because-no-await-boundary-wraps-it.md) — Make Remix deferred data render correctly by wiring the loader, suspense boundary, and fallback together.
- [Express Mounts a Router at the Wrong Path and Every Nested Route Returns `Cannot GET /api/...`](https://bfzli.com/express-mounts-a-router-at-the-wrong-path-and-every-nested-route-returns-cannot-get-api.md) — Fix router mounting mistakes that make Express serve 404s for routes that exist in the child router.
- [Deno Fails to Run an npm Package Because `npm:` Imports Need an Explicit Permission or Lockfile Entry](https://bfzli.com/deno-fails-to-run-an-npm-package-because-npm-imports-need-an-explicit-permission-or-lockfile-entry.md) — Fix Deno package loading when an npm dependency is blocked, unresolved, or missing from the module graph.
- [React Native Android Fails with `Plugin [id: 'com.facebook.react'] was not found`](https://bfzli.com/react-native-android-fails-with-plugin-id-com-facebook-react-was-not-found.md) — Resolve the Gradle plugin lookup failure that blocks Android builds after a React Native upgrade or template change.
- [Hono Returns a CORS Failure When `Access-Control-Allow-Headers` Omits `Content-Type`](https://bfzli.com/hono-returns-a-cors-failure-when-access-control-allow-headers-omits-content-type.md) — Fix Hono responses that fail browser preflight because the server does not allow the request headers the client sends.
- [Cloudflare Workers Reject a WebSocket Upgrade Because the Response Is Not a 101 Switching Protocols Handshake](https://bfzli.com/cloudflare-workers-reject-a-websocket-upgrade-because-the-response-is-not-a-101-switching-protocols-handshake.md) — A WebSocket route fails when the Worker returns the wrong upgrade response shape.
- [Node Resolves the Wrong File from `package.json` `exports` When the Default Condition Is Missing](https://bfzli.com/node-resolves-the-wrong-file-from-package-json-exports-when-the-default-condition-is-missing.md) — A package can load the wrong build target if `exports` does not declare the condition Node is using.
- [Electron Exposes `ipcRenderer` as `undefined` When Context Isolation Blocks the Preload Bridge](https://bfzli.com/electron-exposes-ipcrenderer-as-undefined-when-context-isolation-blocks-the-preload-bridge.md) — A renderer cannot access Electron APIs directly when context isolation removes the preload bridge.
- [Remix Sends Errors to the Wrong Boundary When a Loader Throws Outside Its Route](https://bfzli.com/remix-sends-errors-to-the-wrong-boundary-when-a-loader-throws-outside-its-route.md) — A thrown loader error can skip the expected boundary when the route hierarchy does not match the failing segment.
- [Next.js Client Navigation Stays Stuck on a Stale Page After `router.refresh()`](https://bfzli.com/next-js-client-navigation-stays-stuck-on-a-stale-page-after-router-refresh.md) — `router.refresh()` does not update a page when client state or caching keeps the old UI alive.
- [Bun Locks SQLite During Overlapping Writes with `SQLITE_BUSY`](https://bfzli.com/bun-locks-sqlite-during-overlapping-writes-with-sqlite-busy.md) — Concurrent writes in Bun can stall or fail when SQLite holds a transaction lock too long.
- [Astro Returns 404 When a Route Endpoint Lives in the Wrong Folder](https://bfzli.com/astro-returns-404-when-a-route-endpoint-lives-in-the-wrong-folder.md) — Astro 404s on an endpoint when the file is placed outside the route convention or named incorrectly.
- [Cloudflare Workers Reject `crypto.createHash()` with `ReferenceError: crypto is not defined`](https://bfzli.com/cloudflare-workers-reject-crypto-createhash-with-referenceerror-crypto-is-not-defined.md) — A Node crypto API crashes in Workers because the runtime exposes Web Crypto, not `node:crypto` globals.
- [Node.js Fails to Start a Published CLI with Error: Cannot find module '/package.json'](https://bfzli.com/node-js-fails-to-start-a-published-cli-with-error-cannot-find-module-package-json.md) — A packaged CLI crashes because the entrypoint resolves package metadata from the wrong location.
- [Hono Cannot Match `c.req.param()` When a Static Route Shadows a Dynamic One](https://bfzli.com/hono-cannot-match-c-req-param-when-a-static-route-shadows-a-dynamic-one.md) — Route order in Hono can hide dynamic params and make `c.req.param()` return empty values.
- [Astro Throws ReferenceError: window is not defined When a Browser-Only Import Runs on the Server](https://bfzli.com/astro-throws-referenceerror-window-is-not-defined-when-a-browser-only-import-runs-on-the-server.md) — Astro SSR crashes when a module touches `window` during server rendering.
- [Vite Serves 404s for Assets After a Production Build Because the Base Path Is Wrong](https://bfzli.com/vite-serves-404s-for-assets-after-a-production-build-because-the-base-path-is-wrong.md) — Built assets 404 in production when Vite emits URLs for the wrong base path.
- [Vite Resolves the Wrong Package in a pnpm Workspace Because tsconfig Paths Leak Into Build Imports](https://bfzli.com/vite-resolves-the-wrong-package-in-a-pnpm-workspace-because-tsconfig-paths-leak-into-build-imports.md) — A pnpm monorepo can resolve a local source file instead of the published package entry point and break the build.
- [Next.js App Router Serves Stale Data Because a Server Component Fetch Is Cached](https://bfzli.com/next-js-app-router-serves-stale-data-because-a-server-component-fetch-is-cached.md) — Next.js can reuse a server component fetch result unless you set the right cache mode or revalidation behavior.
- [React Native Fails to Bundle When a Shared Module Imports Node Built-ins](https://bfzli.com/react-native-fails-to-bundle-when-a-shared-module-imports-node-built-ins.md) — Metro stops bundling when shared code pulls in fs, path, or crypto that the React Native runtime cannot provide.
- [Point a Custom Domain at Cloudflare Pages Without Leaving the Site on the Default Subdomain](https://bfzli.com/point-a-custom-domain-at-cloudflare-pages-without-leaving-the-site-on-the-default-subdomain.md) — Cloudflare Pages stays on the generated pages.dev hostname until DNS and the Pages custom domain are configured together.
- [SvelteKit Throws ReferenceError: document is not defined During Server-Side Rendering](https://bfzli.com/sveltekit-throws-referenceerror-document-is-not-defined-during-server-side-rendering.md) — SvelteKit SSR crashes when a component touches document before the browser runs it; isolate browser-only code and gate it behind client checks.
- [Cloudflare Pages Functions Read undefined Environment Variables at Runtime](https://bfzli.com/cloudflare-pages-functions-read-undefined-environment-variables-at-runtime.md) — Make Cloudflare Pages Functions see bound secrets and vars instead of undefined values.
- [Next.js Cannot Optimize Images from an Unconfigured Remote Host](https://bfzli.com/next-js-cannot-optimize-images-from-an-unconfigured-remote-host.md) — Configure next/image so remote images stop failing with host validation and optimization errors.
- [Hono Cannot Read c.req.param() After a Middleware Forgets next()](https://bfzli.com/hono-cannot-read-c-req-param-after-a-middleware-forgets-next.md) — Fix missing route params in Hono by preserving middleware flow and route context.
- [Cloudflare Workers Fail with TypeError: Body has already been used for Request](https://bfzli.com/cloudflare-workers-fail-with-typeerror-body-has-already-been-used-for-request.md) — Understand why a consumed Request body cannot be read twice in Workers and how to clone or buffer it safely.
- [Express Returns req.body Undefined When JSON Middleware Runs Too Late](https://bfzli.com/express-returns-req-body-undefined-when-json-middleware-runs-too-late.md) — Fix req.body staying undefined in Express by placing JSON parsing middleware before your route handlers.
- [Deploying a Static Site to GitHub Pages Breaks Asset URLs Under a Repository Path](https://bfzli.com/deploying-a-static-site-to-github-pages-breaks-asset-urls-under-a-repository-path.md) — Why a site works locally but 404s on GitHub Pages when assets resolve from the domain root instead of the repo path.
- [Design a TypeScript SDK with Multiple Entry Points Without Breaking Imports](https://bfzli.com/design-a-typescript-sdk-with-multiple-entry-points-without-breaking-imports.md) — How to publish a typed SDK with subpath exports, preserved types, and stable import paths for ESM and CommonJS.
- [Remix Returns 405 Method Not Allowed When a Form Submits to the Wrong Route](https://bfzli.com/remix-returns-405-method-not-allowed-when-a-form-submits-to-the-wrong-route.md) — Why a Remix form posts to a route without an action and how route matching determines which loader or action runs.
- [Node Fails to Connect to localhost with ECONNREFUSED ::1 on a Local Server](https://bfzli.com/node-fails-to-connect-to-localhost-with-econnrefused-1-on-a-local-server.md) — Why Node tries IPv6 loopback first for localhost and how to match your server bind address to the resolved address.
- [React Native on Android Throws ReferenceError: window is not defined During Module Initialization](https://bfzli.com/react-native-on-android-throws-referenceerror-window-is-not-defined-during-module-initialization.md) — Why browser globals break during React Native startup on Android and how to move that code behind a native-safe boundary.
- [Bun Throws ERR_REQUIRE_ESM When a CommonJS File Loads an ESM Package](https://bfzli.com/bun-throws-err-require-esm-when-a-commonjs-file-loads-an-esm-package.md) — Why Bun hits ERR_REQUIRE_ESM on mixed module boundaries and how to make the import path match the package format.
- [Next.js Environment Variables Return Undefined in the Browser After Build](https://bfzli.com/next-js-environment-variables-return-undefined-in-the-browser-after-build.md) — Why process.env values disappear in client code after a Next.js production build, and how to expose the right variables safely.
- [Cloudflare Workers Reject POST Requests with a CORS Preflight Failure](https://bfzli.com/cloudflare-workers-reject-post-requests-with-a-cors-preflight-failure.md) — Return the right CORS headers from a Worker so browser preflight requests stop failing.
- [Deno Cron Tasks See DENO_ENV Undefined in Scheduled Runs](https://bfzli.com/deno-cron-tasks-see-deno-env-undefined-in-scheduled-runs.md) — Make scheduled Deno jobs read environment variables reliably instead of getting undefined at runtime.
- [Electron Throws Refused to Execute Inline Script When a Sandboxed Preload Loads Local HTML](https://bfzli.com/electron-throws-refused-to-execute-inline-script-when-a-sandboxed-preload-loads-local-html.md) — Fix CSP failures when Electron loads local HTML with a sandboxed preload and inline script blocked.
- [Next.js Hydration Mismatch: Random UUIDs Render Different HTML on Server and Client](https://bfzli.com/next-js-hydration-mismatch-random-uuids-render-different-html-on-server-and-client.md) — Fix hydration errors caused by non-deterministic UUIDs in server-rendered Next.js components.
- [Node.js Fails with bin Not Found After Publishing a Package to npm](https://bfzli.com/node-js-fails-with-bin-not-found-after-publishing-a-package-to-npm.md) — Fix npm packages that install but do not expose the expected CLI command.
- [Nuxt Generates 404s for Nested Routes During Static Site Deployment](https://bfzli.com/nuxt-generates-404s-for-nested-routes-during-static-site-deployment.md) — Fix missing pages when Nuxt static generation doesn't emit the routes your host expects.
- [SQLite Returns SQLITE_BUSY During Concurrent Writes in Drizzle ORM](https://bfzli.com/sqlite-returns-sqlite-busy-during-concurrent-writes-in-drizzle-orm.md) — Reduce SQLite write contention when multiple requests try to write through Drizzle at once.
- [Programmatically Access Lummi AI Images with Lummi SDK](https://bfzli.com/programmatically-access-lummi-ai-images-with-lummi-sdk.md) — A walkthrough on how to use the Lummi SDK to access images programmatically.
- [Extract Geolocation Data From an IP Programmatically and Instantly](https://bfzli.com/extract-geo-location-data-from-an-ip-programmatically-instantly.md) — Easily extract geolocation data from an IP address using a simple npm package.
- [MongoError: bad auth Authentication failed through URI string](https://bfzli.com/mongo-error-bad-auth-authentication-failed.md) — How to fix the MongoError: bad auth Authentication failed through URI string error, when it happens and some common reasons why it might be happening.
- [How I Accidentally Stepped on a Phishing Site and Then Helped Shut It Down](https://bfzli.com/how-i-accidentally-stepped-on-a-phishing-site-and-then-helped-shut-it-down.md) — From receiving a phishing email to the site being taken down within 24 hours, this is a story we can all learn from.

## Elsewhere

- Email: bfzli@hotmail.com
- LinkedIn: https://www.linkedin.com/in/benjaminfzl
- GitHub: https://github.com/bfzli
- X: https://twitter.com/bfzli
