{"record":{"id":"e62f4a331edeeabf","repo":"dotnet/runtime","slug":"unrecognized-asset-behavior-asset-behavior-for","errorCode":null,"errorMessage":"Unrecognized asset behavior:${asset.behavior}, for asset ${asset.name}","messagePattern":"Unrecognized asset behavior:(.+?), for asset (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/mono/browser/runtime/assets.ts","lineNumber":61,"sourceCode":"            const lastSlash = virtualName.lastIndexOf(\"/\");\n            let parentDirectory = (lastSlash > 0)\n                ? virtualName.substring(0, lastSlash)\n                : browserVirtualAppBase;\n            let fileName = (lastSlash > 0)\n                ? virtualName.substring(lastSlash + 1)\n                : virtualName;\n            if (fileName.startsWith(\"/\"))\n                fileName = fileName.substring(1);\n            if (!parentDirectory.startsWith(\"/\"))\n                parentDirectory = browserVirtualAppBase + parentDirectory;\n\n            mono_log_debug(() => `Creating file '${fileName}' in directory '${parentDirectory}'`);\n            Module.FS_createPath(\"/\", parentDirectory, true, true);\n            Module.FS_createDataFile(parentDirectory, fileName, bytes, true /* canRead */, true /* canWrite */, true /* canOwn */);\n            break;\n        }\n        default:\n            throw new Error(`Unrecognized asset behavior:${asset.behavior}, for asset ${asset.name}`);\n    }\n\n    if (asset.behavior === \"assembly\") {\n        // this is reading flag inside the DLL about the existence of PDB\n        // it doesn't relate to whether the .pdb file is downloaded at all\n        const hasPdb = cwraps.mono_wasm_add_assembly(virtualName, offset!, bytes.length);\n\n        if (!hasPdb) {\n            const index = loaderHelpers._loaded_files.findIndex(element => element.file == virtualName);\n            loaderHelpers._loaded_files.splice(index, 1);\n        }\n    } else if (asset.behavior === \"pdb\") {\n        cwraps.mono_wasm_add_assembly(virtualName, offset!, bytes.length);\n    } else if (asset.behavior === \"icu\") {\n        wasm_load_icu_data(offset!);\n    } else if (asset.behavior === \"resource\") {\n        cwraps.mono_wasm_add_satellite_assembly(virtualName, asset.culture || \"\", offset!, bytes.length);\n    }","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/dotnet/runtime/blob/60108ba66eb7d1d12f595480091b4ad80a24b172/src/mono/browser/runtime/assets.ts#L43-L79","documentation":"Thrown by `instantiate_asset` in the .NET WebAssembly asset loader when an asset's `behavior` field does not match any case of the dispatch switch (dotnetwasm, js-module-diagnostics, symbols, resource, assembly, pdb, heap, icu, vfs). The runtime cannot decide how to load the asset, so it errors rather than silently skipping it. This is a configuration/contract error in the asset manifest produced by the .NET WASI/browser build.","triggerScenarios":"The runtime iterates `runtimeHelpers.config.assets` and calls `instantiate_asset(asset, url, bytes)`. If `asset.behavior` is undefined, null, a typo, or a value produced by a newer SDK that this runtime build does not understand, execution falls to the `default:` branch at src/mono/browser/runtime/assets.ts:60-61. Custom asset entries injected through `assets` config that don't use one of the enumerated behaviors also trip it.","commonSituations":"Hand-editing the `assets` JSON in the runtime config and misspelling a behavior; mixing a runtime bundle with a `dotnet.runtime.js` from a different SDK that emits behaviors this loader doesn't know; downgrading the runtime bundle while keeping a config generated by a newer SDK.","solutions":["Inspect `config.assets` at runtime (log `runtimeHelpers.config.assets`) and find the entry whose `behavior` is not in {dotnetwasm, js-module-diagnostics, symbols, resource, assembly, pdb, heap, icu, vfs}.","Re-generate the assets config by re-running the .NET wasm publish step with the runtime that is actually loaded.","Remove or correct any hand-added asset entries with an unsupported behavior.","If a genuinely new behavior is required, extend the switch in assets.ts:25 to handle it."],"exampleFix":"// before: typo'd behavior in the config\nconfig.assets = [{ name: 'MyLib.dll', behavior: 'asembly' }]; // throws\n\n// after: use a supported behavior literal\nconfig.assets = [{ name: 'MyLib.dll', behavior: 'assembly' }];","handlingStrategy":"validation","validationCode":"const KNOWN_BEHAVIORS = new Set(['dotnetwasm','js-module-diagnostics','symbols','resource','assembly','pdb','heap','icu','vfs']);\nfunction validateAssets (assets) {\n  return assets.filter(a => !KNOWN_BEHAVIORS.has(a.behavior));\n}\nconst bad = validateAssets(runtimeHelpers.config.assets || []); if (bad.length) console.error('bad assets', bad);","typeGuard":"type AssetBehavior = 'dotnetwasm'|'js-module-diagnostics'|'symbols'|'resource'|'assembly'|'pdb'|'heap'|'icu'|'vfs';\nfunction isAssetBehavior (v: unknown): v is AssetBehavior {\n  return typeof v === 'string' && ['dotnetwasm','js-module-diagnostics','symbols','resource','assembly','pdb','heap','icu','vfs'].includes(v);\n}","tryCatchPattern":null,"preventionTips":["Never hand-edit the generated assets config; regenerate it via `dotnet publish`.","If you must inject custom assets, restrict to the known behaviors and validate before passing to the runtime.","Log `runtimeHelpers.config.assets` at startup in dev builds to catch typos early."],"tags":["assets","configuration","runtime","loader","typescript"],"backgroundTag":null,"analyzedSha":"60108ba66eb7d1d12f595480091b4ad80a24b172","analyzedAt":"2026-08-10T18:54:11.478Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}