{"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/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/wwwroot/dotnet-web-worker.js#L22-L55","documentation":"Thrown when the dotnet-worker exports object has been initialized (workerExports is non-empty) but the requested dotted method path (e.g. 'MyLib.Foo.Bar') does not resolve to a function. The path is split on '.' and walked with reduce; any missing segment, or a non-function leaf, triggers this.","triggerScenarios":"Calling worker.postMessage with a method string whose namespace/type/method does not match the [JSExport] surface of the loaded assembly; method name typo; the export is on a different type than expected; the export exists but is a property/constant, not a function.","commonSituations":"Renaming an exported method in C# without updating the JS caller; using the wrong assemblyName so a different (or older) export surface is loaded; casing mismatch (C# is case-sensitive); calling a static field rather than a static method.","solutions":["Log Object.keys(workerExports) and inspect the actual exported surface to confirm the path.","Match the method string exactly to the [JSExport] namespace.type.method, case-sensitive.","Ensure the assemblyName passed to init matches the assembly containing the export.","If the export was renamed, update the JS caller; do not rely on duck-typing across versions."],"exampleFix":"// before\nworker.postMessage({ method: 'MyLib.Calc.Add', args: [1,2], requestId });\n// JSExport is on MyLib.Calculator.Add → 'Calc.Add is not a function'\n\n// after — match the exported type name exactly\nworker.postMessage({ method: 'MyLib.Calculator.Add', args: [1,2], requestId });","handlingStrategy":"validation","validationCode":"// Validate the method path resolves before posting\nfunction methodExists(exports: any, dotted: string): boolean {\n  const fn = dotted.split('.').reduce((o, k) => o?.[k], exports);\n  return typeof fn === 'function';\n}\nif (!methodExists(workerExports, method)) {\n  console.error(`Available exports:`, Object.keys(workerExports));\n  throw new Error(`Method not found: ${method}`);\n}","typeGuard":"function isExportedFunction(exports: any, path: string): exports is Record<string, Function> {\n  const fn = path.split('.').reduce((o, k) => o?.[k], exports);\n  return typeof fn === 'function';\n}","tryCatchPattern":"try {\n  const result = await fn(...args);\n  self.postMessage({ type: 'result', requestId, result });\n} catch (e) {\n  if (/Method not found/.test((e as Error).message)) {\n    self.postMessage({ type: 'result', requestId, error: `${e.message}. Available: ${Object.keys(workerExports).join(', ')}` });\n  } else throw e;\n}","preventionTips":["Keep a single source of truth for exported method names (codegen from [JSExport] attributes).","Pin @microsoft/signalr and worker runtime versions together.","Log available exports whenever a method-not-found occurs."],"tags":["web-worker","blazor","jsexport","programming-error","api-mismatch"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}