{"record":{"id":"fffba7245f606562","repo":"dotnet/aspnetcore","slug":"method-not-found-method","errorCode":null,"errorMessage":"Method not found: ${method}","messagePattern":"Method not found: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/wwwroot/dotnet-web-worker.js","lineNumber":40,"sourceCode":"    }\n}\n\nself.addEventListener('message', async (e) => {\n    if (e.data.type === 'init') {\n        await initialize(e.data.dotnetJsUrl, e.data.assemblyName);\n        return;\n    }\n\n    const { method, args, requestId } = e.data;\n\n    try {\n        if (Object.keys(workerExports).length === 0) {\n            throw new Error(startupError || \"Worker .NET runtime not loaded\");\n        }\n\n        const fn = method.split('.').reduce((obj, part) => obj?.[part], workerExports);\n        if (typeof fn !== 'function') {\n            throw new Error(`Method not found: ${method}`);\n        }\n\n        const result = await fn(...args);\n        self.postMessage({ type: \"result\", requestId, result }, collectTransferables(result));\n    } catch (err) {\n        self.postMessage({ type: \"result\", requestId, error: err?.message ?? String(err) });\n    }\n});\n\nfunction collectTransferables(value) {\n    if (ArrayBuffer.isView(value)) return [value.buffer];\n    if (value instanceof ArrayBuffer) return [value];\n    return [];\n}\n","sourceCodeStart":22,"sourceCodeEnd":55,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/92f07e298d5c5a629385b8b0a32d7164b1b53906/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/wwwroot/dotnet-web-worker.js#L22-L55","documentation":"The worker resolves the dotted 'method' path against workerExports (populated from getAssemblyExports) and checks typeof === 'function'. If the path does not resolve to a function, the method is not exported (missing [JSExport]) or the path/namespace is wrong.","triggerScenarios":"Calling a method name that does not match an exported [JSExport] method; namespace.type.method mismatch; method is not public/static; wrong assembly name passed to init so exports were empty.","commonSituations":"Method not annotated with [JSExport]; wrong assembly name in the init message; method renamed; path casing or segmentation wrong.","solutions":["Ensure the target method is annotated [JSExport] and is public/static.","Match the path exactly (Namespace.Type.Method) against workerExports keys.","Verify the assemblyName passed to init so the correct exports were loaded.","Log Object.keys(workerExports) in the worker to see what is actually exported."],"exampleFix":"// before (not exported, or wrong path)\nworker.postMessage({ method: 'Compute', args: [], requestId: 1 });\n\n// after (full path + [JSExport] on the C# method)\n// C#: [JSExport] public static int Compute(int x) => x;\nworker.postMessage({ method: 'MyApp.Worker.Compute', args: [42], requestId: 1 });","handlingStrategy":"validation","validationCode":"// From the main thread, validate the method path before posting.\n// (workerExports lives in the worker; log it once after ready.)\n// In the worker, add a debug log:\nself.postMessage({ type: 'debug', exports: Object.keys(workerExports) });","typeGuard":"// Resolve a dotted path and confirm it is a function.\nfunction resolveFn(exports, path) {\n  const fn = path.split('.').reduce((o, k) => o?.[k], exports);\n  return typeof fn === 'function' ? fn : null;\n}","tryCatchPattern":null,"preventionTips":["Annotate every callable C# method with [JSExport].","Use the exact Namespace.Type.Method path in the message.","Pass the correct assemblyName to init so exports are populated."],"tags":["blazor","web-worker","method-resolution","jsexport"],"analyzedSha":"92f07e298d5c5a629385b8b0a32d7164b1b53906","analyzedAt":"2026-08-07T06:05:17.747Z","schemaVersion":2},"datasetVersion":"2026-08-07T15:17:06.553Z"}