# TL;DR
workerd only treats non-JS imports specially when a [rules] entry in wrangler.toml matches the file. Add a rule mapping the file type to its module kind (Text, Data, CompiledWasm, or ESModule) and rebuild. Without a matching rule, the import falls back to plain text, which breaks wasm instantiation, binary parsing, and anything expecting structured bytes.

```text
workerd error: module rule did not match, import treated as text
```

1. Identify the failing import in your entry file. Common cases: importing "./data.bin", "./module.wasm", or "./template.txt" directly.

Expected: you can name the file extension that is being mishandled.

2. Check your current rules in wrangler.toml:

```
grep -A5 "\[rules\]" wrangler.toml
```

Expected: either no [rules] section (the bug) or rules that do not cover the extension in question.

3. Add a rule for the file type. For a WebAssembly module:

```toml
[[rules]]
type = "CompiledWasm"
globs = ["**/*.wasm"]
```

For plain text you want as a string: type = "Text" with globs ["**/*.txt"]. For raw bytes: type = "Data" with globs ["**/*.bin"].

Expected: the new section parses; wrangler deploy --dry-run no longer warns about the import.

4. Change the import site if needed. CompiledWasm imports give you a module namespace you pass to WebAssembly.instantiate; Text imports give you the file contents as a string; Data imports give you an ArrayBuffer.

Expected: the value at the import site is the right type, not a text blob.

5. Rebuild and redeploy, then verify the runtime type with a log line or a test request.

Expected: wasm instantiates, binary parses, or text reads as expected. The "treated as text" symptom is gone.

## Use this when
- Importing .wasm, .bin, .txt, .html, or .css into a worker and getting the wrong type or a build error.
- A library ships non-JS assets and the bundler inlines them as text.
- The error message explicitly mentions a module rule not matching.

## Not for this skill when
- The import is a normal .js/.ts/.mjs module that fails to resolve. That is an entry-point or bundling issue, not rules.
- The file type is already covered by a rule but the content is wrong. Check the asset itself.
- You are using the assets feature (Workers Static Assets) rather than module rules; those are different mechanisms.

## Variant phrasings
- wrangler rules wasm import not working
- cloudflare workers import text file as string
- module rule globs not matching binary import
- workers "treated as text" import

## Why it happens
workerd's module system is explicit: the runtime will not guess that foo.wasm should be compiled or that data.bin is bytes. The [rules] table is the mapping from file globs to module types, evaluated at build time. Anything unmatched defaults to Text. This is a deliberate design choice so bundles stay predictable, but it surprises anyone used to bundlers that auto-detect wasm or raw imports.

## Edge cases
- Rules are evaluated in order and the first match wins. A broad "**/*" Text rule above your wasm rule will swallow the wasm files. Put specific rules first.
- Rules apply at build/upload time, not per request. Changing rules requires a rebuild and redeploy (or dev restart); hot reload of code alone will not pick them up.
- Node.js built-in-style imports (node:fs etc.) are a different system (nodejs_compat), not module rules. Do not try to fix those with globs.
- If a dependency in node_modules contains the asset, your rule globs must cover its path too; scoping globs to ./src only will miss it.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_NVGvmvPFIyafkJfradU3pQ
