{"record":{"id":"a0090468c7a3bb90","repo":"schollz/croc","slug":"method-failed","errorCode":null,"errorMessage":"${method} failed","messagePattern":"(.+?) failed","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"web/public/croc-worker.js","lineNumber":43,"sourceCode":"}\n\nfunction transferables(value, output = []) {\n  if (value instanceof Uint8Array) {\n    output.push(value.buffer);\n  } else if (value && typeof value === \"object\") {\n    for (const child of Object.values(value)) transferables(child, output);\n  }\n  return output;\n}\n\nself.addEventListener(\"message\", async (event) => {\n  const { id, method, args = [] } = event.data;\n  try {\n    await initialize();\n    const fn = self.crocWasm[method];\n    if (typeof fn !== \"function\") throw new Error(`Unknown WASM method: ${method}`);\n    const response = fn(...args);\n    if (!response.ok) throw new Error(response.error || `${method} failed`);\n    self.postMessage({ id, result: response.value }, transferables(response.value));\n  } catch (error) {\n    self.postMessage({\n      id,\n      error: error instanceof Error ? error.message : String(error),\n    });\n  }\n});\n\nvoid initialize().catch((error) => {\n  self.postMessage({\n    id: 0,\n    error: error instanceof Error ? error.message : String(error),\n  });\n});\n","sourceCodeStart":25,"sourceCodeEnd":59,"githubUrl":"https://github.com/schollz/croc/blob/e25f1bdc04f07f094d50b0a1bf67e2563944b57a/web/public/croc-worker.js#L25-L59","documentation":"The worker dispatched a method call on the crocWasm bridge and the Go side returned {ok: false} without a specific error string, so the worker substitutes the generic '<method> failed'. It is the catch-all for any Go-level failure inside the requested WASM function (hashing, PAKE, encryption, code generation) that did not produce its own message. The real cause is only distinguishable by which method was invoked.","triggerScenarios":"Calling engine methods with malformed inputs, e.g. pakeUpdate with a handle that was already consumed; passing empty or wrong-length Uint8Arrays to crypto functions; a Go panic recovered into the generic ok:false result; memory pressure aborting the wasm computation.","commonSituations":"Sending detached ArrayBuffers to the worker (they were transferred in a previous postMessage); reusing one-shot PAKE handles across retries; Safari iOS wasm memory limits on large hashing operations.","solutions":["Identify which WASM method was called (it appears in the message) and validate its inputs before dispatch","Check that byte arrays are non-detached and of the expected length before posting to the worker","Ensure one-shot handles (hashInit/pakeInit results) are not reused after an error or retry","Inspect the Go side of the bridge: add or surface response.error so the real failure text reaches the caller"],"exampleFix":"// before: caller posts a possibly detached buffer\nworker.postMessage({ id, method: \"encrypt\", args: [data.buffer, key] });\n\n// after: validate inputs and re-copy before dispatch\nif (data.byteLength === 0) throw new Error(\"empty plaintext\");\nworker.postMessage({ id, method: \"encrypt\", args: [new Uint8Array(data), key] });","handlingStrategy":"try-catch","validationCode":"// Reject detached/empty buffers before posting to the worker\nfunction assertBytes(b, name) {\n  if (!(b instanceof Uint8Array) || b.byteLength === 0) throw new Error(`${name} must be a non-empty Uint8Array`);\n  if (b.buffer.byteLength === 0) throw new Error(`${name} buffer is detached`);\n}","typeGuard":null,"tryCatchPattern":"// RPC caller: wrap each call, annotate with the method name for diagnosis\ntry {\n  return await rpc.call(method, args);\n} catch (e) {\n  throw new Error(`${method}: ${e.message}`, { cause: e });\n}","preventionTips":["Never reuse one-shot handles (hashInit/pakeInit) after an error","Copy (not transfer) buffers you need to keep after postMessage","Improve the Go bridge to always fill response.error so generic failures become specific"],"tags":["wasm","rpc","generic-error","web-worker"],"backgroundTag":null,"analyzedSha":"e25f1bdc04f07f094d50b0a1bf67e2563944b57a","analyzedAt":"2026-08-15T12:53:39.096Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}