{"record":{"id":"41b4cc4346396bd5","repo":"dotnet/runtime","slug":"coreclr-wasm-rtlrestorecontext-tag-was-not-prese","errorCode":null,"errorMessage":"__coreclr_wasm_rtlrestorecontext_tag was not preserved by the linker or optimizer","messagePattern":"__coreclr_wasm_rtlrestorecontext_tag was not preserved by the linker or optimizer","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"src/native/libs/Common/JavaScript/host/assets.ts","lineNumber":124,"sourceCode":"// Builds the `webcil` import object. For R2R images (tableSize > 0) the module imports the runtime's\n// stack pointer, exception tag, indirect-call table and base globals; this also grows the table.\n// These import names and the webcilVersion/getWebcilPayload/fillWebcilTable handshake in\n// finishWebcilInstance are the R2R Webcil-in-Wasm host ABI defined by crossgen's WasmObjectWriter\n// (src/coreclr/tools/Common/Compiler/ObjectWriter/WasmObjectWriter.cs, CreateDefaultGlobalImports/\n// WriteExports). Keep in sync with the corerun host\n// (src/coreclr/hosts/corerun/wasm/libCorerun.js, BrowserHost_ExternalAssemblyProbe). Unlike corerun,\n// which parses data segment 0 for payloadSize/tableSize, this loader receives them from boot config.\nfunction buildWebcilImports(memory: WebAssembly.Memory, payloadPtr: number, tableSize: number): Record<string, WebAssembly.ImportValue> {\n    const webcilImports: Record<string, WebAssembly.ImportValue> = { memory };\n    if (tableSize > 0) {\n        const stackPointer = _ems_.wasmExports?.__stack_pointer;\n        const rtlRestoreContextTag = _ems_.wasmExports?.__coreclr_wasm_rtlrestorecontext_tag;\n        const asyncContinuation = _ems_.wasmExports?.__async_continuation;\n        if (!stackPointer) {\n            throw new Error(\"__stack_pointer was not preserved by the linker or optimizer\");\n        }\n        if (!rtlRestoreContextTag) {\n            throw new Error(\"__coreclr_wasm_rtlrestorecontext_tag was not preserved by the linker or optimizer\");\n        }\n        if (!asyncContinuation) {\n            throw new Error(\"__async_continuation was not preserved by the linker or optimizer\");\n        }\n        const tableStartIndex = _ems_.wasmTable.length;\n        _ems_.wasmTable.grow(tableSize);\n        webcilImports.stackPointer = stackPointer;\n        webcilImports.rtlRestoreContextTag = rtlRestoreContextTag as unknown as WebAssembly.ImportValue;\n        webcilImports.asyncContinuation = asyncContinuation as unknown as WebAssembly.ImportValue;\n        webcilImports.table = _ems_.wasmTable;\n        webcilImports.tableBase = new WebAssembly.Global({ value: \"i32\", mutable: false }, tableStartIndex);\n        webcilImports.imageBase = new WebAssembly.Global({ value: \"i32\", mutable: false }, payloadPtr);\n    }\n    return webcilImports;\n}\n\n// Copies the payload into the allocated buffer, fills the R2R table (if any) and registers the\n// loaded image for BrowserHost_ExternalAssemblyProbe.","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/dotnet/runtime/blob/60108ba66eb7d1d12f595480091b4ad80a24b172/src/native/libs/Common/JavaScript/host/assets.ts#L106-L142","documentation":"Thrown by buildWebcilImports() (src/native/libs/Common/JavaScript/host/assets.ts:114) for an R2R webcil asset. The RTL restore-context tag (__coreclr_wasm_rtlrestorecontext_tag) is the wasm exception/tag export used by R2R images to restore execution context during exception handling; if it is missing from wasmExports, the R2R import set is incomplete and the host refuses to continue.","triggerScenarios":"R2R webcil instantiation (tableSize > 0) where _ems_.wasmExports.__coreclr_wasm_rtlrestorecontext_tag is falsy. The runtime wasm module was linked without preserving this export.","commonSituations":"Custom linker/optimizer configuration stripping exception/tag exports; runtime built without the R2R host-ABI exports; mismatch between an R2R assembly's expected ABI and the runtime that loads it.","solutions":["Rebuild the runtime with the default build that preserves __coreclr_wasm_rtlrestorecontext_tag.","Match the R2R assembly toolchain version to the runtime version so the export set agrees.","When customizing the build, explicitly export the tag in the linker configuration."],"exampleFix":"# before: export list omits the tag -> 'was not preserved by the linker or optimizer'\n\n# after\nemcc ... -s EXPORTED_FUNCTIONS=[...,__coreclr_wasm_rtlrestorecontext_tag,...]","handlingStrategy":"validation","validationCode":"function runtimeExportsRtlTag(): boolean {\n  return !!((globalThis as any).Module?.wasmExports?.__coreclr_wasm_rtlrestorecontext_tag);\n}","typeGuard":"function hasRtlRestoreTag(exp: any): exp is { __coreclr_wasm_rtlrestorecontext_tag: WebAssembly.Global } {\n  return exp && !!exp.__coreclr_wasm_rtlrestorecontext_tag;\n}","tryCatchPattern":null,"preventionTips":["Use the default runtime build that keeps exception/tag exports.","Do not strip the host-ABI exports when customizing the linker.","Keep the runtime version aligned with the R2R assembly producer."],"tags":["webcil","r2r","linker","exceptions","build"],"backgroundTag":null,"analyzedSha":"60108ba66eb7d1d12f595480091b4ad80a24b172","analyzedAt":"2026-08-10T18:54:11.478Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}