顯示包含「Web Development」標籤的文章。顯示所有文章
顯示包含「Web Development」標籤的文章。顯示所有文章

2026-06-19

How to Fix Blazor Kestrel Error: Unsupported Compression Method for Static HTML

If you are building a Blazor application and need to serve static HTML files directly (like a design system, documentation, or legacy pages), you probably tossed them straight into your wwwroot folder.

Everything works beautifully in your production environment. But when you hit F5 to test locally, you are greeted with a nasty System.IO.InvalidDataException crash in your Kestrel server logs:

fail: Microsoft.AspNetCore.Server.Kestrel Connection id "...", Request id "...": An unhandled exception was thrown by the application. System.IO.InvalidDataException: The archive entry was compressed using an unsupported compression method. at System.IO.Compression.Inflater.Inflate(FlushCode flushCode) ... at Microsoft.AspNetCore.Watch.BrowserRefresh.ResponseStreamWrapper.DisposeAsync()

The Root Cause: Local Browser Refresh Tooling

At first this looked strange, because I was not using any custom compression code. The problem turned out to be related to the development-time BrowserLink / Browser Refresh pipeline in ASP.NET Core, not the HTML file itself.

This error is not a bug in my code, nor is it an issue with the HTML files. It is caused by a known development-time bug in ASP.NET Core's Hot Reload / Browser Refresh middleware.

When you run your project locally, Visual Studio (version 2026) or the dotnet watch CLI dynamically injects a tiny JavaScript snippet into your HTML responses. This script allows your browser to automatically refresh when you save changes in your code.

However, when you directly request a static .html file from wwwroot in development, the BrowserRefreshMiddleware attempts to read the underlying data stream to inject its script. If the framework compresses or buffers this static stream under certain local configurations, the middleware misinterprets the compression headers, corrupts the stream, and crashes Kestrel.

In .NET 10, static assets can be processed through the SDK's static web assets pipeline. In development, BrowserLink tries to inject its refresh script into HTML responses. That is usually fine for normal HTML, but if the response is being served through the compressed static asset path, the browser refresh middleware can fail while trying to rewrite it.

That is why the issue appeared only for HTML files and not for images like:

	https://localhost:7075/assets/logo/blazor.png

Images do not get HTML script injection, so they do not hit the same BrowserLink path.

Why does it work in Production?

This issue completely vanishes in production because Hot Reload and Browser Refresh tools are entirely stripped out when your app runs outside of the Development environment.


How to Fix It

Since the problem lies entirely within local development tooling, you can fix it by telling ASP.NET Core to skip loading the browser tools for your debugging profile.

Solution 1: Update launchSettings.json (Recommended)

The cleanest fix is to append an environment variable to your local launch profile. This fixes the issue for anyone pulling down your repository without breaking their global IDE settings.

  1. Open your project's Properties/launchSettings.json file.
  2. Locate the profile you use to run the application (e.g., "https" or "http").
  3. Under the "environmentVariables" object, add "ASPNETCORE_HOSTINGSTARTUPEXCLUDEASSEMBLIES": "Microsoft.WebTools.BrowserLink.Net".

Your configuration file should look like this:

"profiles": { "https": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy", "applicationUrl": "https://localhost:7075;http://localhost:5242", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "ASPNETCORE_HOSTINGSTARTUPEXCLUDEASSEMBLIES": "Microsoft.WebTools.BrowserLink.Net" } } }

Solution 2: Disable via Visual Studio Settings

If you prefer a global fix across your IDE without altering your source control files, you can turn off the features directly inside Visual Studio:

  1. Click the dropdown arrow next to the Hot Reload button (the fire icon 🔥) in the top toolbar and uncheck Enable Hot Reload on File Save.
  2. Click the dropdown arrow next to the Browser Link icon in the toolbar and uncheck Enable Browser Link.

Other quick fixes or debugging (use wisely in Production env):

  1. Clear browser cache and rebuild
    • Close the browser entirely.
    • Delete bin/ and obj/ folders locally.
    • In Visual Studio: Build → Clean Solution, then Build → Build Solution.
    • Run the app fresh (F5).

  2. Disable gzip compression for static files temporarily (test if it's the culprit)
    • Open Program.cs.
    • Look for lines with .UseResponseCompression() or gzip middleware.
    • Temporarily comment them out or add a condition to skip .html files.
    • Rebuild and test.

  3. Added this to [YOUR_PROJECT.csproj]:
    • <DisableBuildCompression>true</DisableBuildCompression>
      or
      <DisableBuildCompression Condition="'$(Configuration)' == 'Debug'">true</DisableBuildCompression>

Summary

When serving raw HTML assets straight out of wwwroot, local stream manipulation by .NET's developer tools can accidentally break payload compression. By excluding BrowserLink.Net from your development startup assemblies, you bypass the buggy middleware entirely, making your local development environment behave exactly like your stable production server.

2026-06-18

How to Install OpenAI Codex CLI on Windows (and Fix 404 Not Found Errors)

Setting up your terminal environment for local AI-assisted engineering tools is amazing—until your initial installation command hits a roadblock. If you attempted to set up OpenAI Codex and were blocked by an registry error, you are not alone.

The Problem: npm error code E404

When running a guessed or outdated package command in the Windows Command Prompt, the npm registry throws a missing resource exception:

C:\Users\User>npm install -g @openai/codex-cli npm error code E404 npm error 404 Not Found - GET https://npmjs.org - Not found npm error 404 The requested resource '@openai/codex-cli@*' could not be found...

Why this happens: The package identifier name @openai/codex-cli does not exist on the npm server. The core executable CLI logic is bundled directly inside the foundational engine scope name.

The Solution: Step-by-Step Installation Guide

Follow these steps to clean up your environment registry context and download the correct global binaries securely:

  1. Run the Correct Package Command: Open your terminal window and point npm to the official, integrated framework tool distribution location:
    npm install -g @openai/codex@latest
  2. Verify Package Linkage Success: Once terminal dependency resolution completes, it will report the package structural allocation:
    added 7 packages in 31s
  3. Query the System Shell Mapping: Confirm your system execution PATH variables accurately point to the newly registered node engine variables by checking the deployment version:
    codex --version
    You will see the active system architecture footprint print out cleanly:
    codex-cli 0.141.0


Launching Your Agent Environment

Now that the CLI is correctly linked to your terminal profile, you can open up your local interactive development session instantly by inputting:

codex --interactive

💡 Troubleshooting Tips for AI IDE Engineers

Missing Binary Fallbacks: On isolated Windows machines, if your global npm prefix scripts are blocked by Execution Policies, bypass npm completely. Head to the official repository releases, download codex-x86_64-pc-windows-msvc.exe, drop it into your local directory, and rename it to codex.exe.

Google Antigravity Mapping: If you are moving this workflow into the Google Antigravity IDE workspace, you don't even need npm dependencies! Use the internal extension channel path instead:

/plugin marketplace add obra/superpowers-marketplace
/plugin install superpowers@superpowers-marketplace

2026-06-08

How to Crawl and Download Your Localhost Site as Static HTML on Windows

Have you ever built a beautiful local web application and needed to extract it into static HTML files? Maybe you want to backup a local database-driven project, preview a static build, or archive a site.

If you are on Windows and tried to install:

winget install GNU.Wget
and you may get error message:
No package found matching input criteria.

or typing a quick wget command into PowerShell like:

wget.exe --no-check-certificate --recursive --page-requisites --adjust-extension --convert-links --no-parent https://localhost:7249/
You probably got smacked with a nasty, confusing error message:
Invoke-WebRequest : A positional parameter cannot be found that accepts argument '--recursive'.

Don't worry, you didn't write the command wrong. You just fell into a classic Windows PowerShell trap! Here is exactly why that happens and how to easily crawl your https://localhost site with the real tool in under two minutes.


The PowerShell identity crisis: Why wget failed

By default, Windows PowerShell uses aliases (shortcuts). When you type wget, PowerShell doesn't actually run the famous GNU Wget data-grabbing tool. Instead, it secretly runs its own built-in command called Invoke-WebRequest.

Because Microsoft’s tool doesn't understand advanced web crawling flags like --recursive or --page-requisites, it crashes instantly.

To fix this, we need to install the authentic, full-powered version of GNU Wget on your system.


Step 1: Install the real GNU wget tool

Windows 10 and 11 come with a built-in package manager called winget. We will use it to pull down the correct software.

  1. Open your PowerShell window.
  2. Run this exact command to target the authentic application ID:
winget install -e --id JernejSimoncic.Wget

(If prompted to accept source agreements, simply type Y and press Enter).


Step 2: Refresh your terminal environment

Once the installer finishes, the system needs to recognize the newly added software paths.

  1. Close your current PowerShell window completely.
  2. Open a brand new PowerShell window.
  3. Navigate to the exact folder where you want your static HTML files to drop:
cd "C:\Users\YourUsername\Desktop\MyStaticSite"

Step 3: Run the magic localhost crawl command

Now we execute the crawl. To bypass PowerShell's fake shortcut, we explicitly add .exe to our command.

If your local development site is running on an HTTPS port (e.g., https://localhost:7249/), execute this line:

wget.exe --no-check-certificate --recursive --page-requisites --adjust-extension --convert-links --no-parent https://localhost:7249/

What do all those flags actually do?

  • --no-check-certificate: Crucial for local dev environments! It forces the crawler to ignore self-signed SSL/TLS certificate warnings.
  • --recursive: Tells the tool to map out your site layout and follow local links automatically.
  • --page-requisites: Grabs all assets required to render the site properly offline (CSS stylesheets, background images, and scripts).
  • --adjust-extension: Automatically appends .html to raw local routing endpoints so your web browser can open them like normal files.
  • --convert-links: Rewrites the internal code paths so your local files point to each other instead of trying to look for the live web server.

How to uninstall it

Open your PowerShell window and run:

winget uninstall JernejSimoncic.Wget

The Result

Once the script finishes downloading, check your directory! You will find a brand-new folder named localhost:7249.

Inside, you will find a fully functional, offline-ready index.html alongside neatly organized folders containing your JavaScript, style sheets, and local media assets. You can open index.html in any browser, and your site layout will render completely intact without requiring your local development server to be turned on!

Developer Note: Keep in mind that static crawlers like wget download raw elements rendered by the server. If your localhost application depends entirely on runtime client-side frameworks (like React or Angular components fetching API data dynamically after the page loads), you may need to use an automated browser script like Puppeteer instead.