{"record":{"id":"adfacfc92cf82194","repo":"wavetermdev/waveterm","slug":"call-methodname-error-respdata-error","errorCode":null,"errorMessage":"call ${methodName} error: ${respData.error}","messagePattern":"call (.+?) error: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"frontend/app/store/wos.ts","lineNumber":140,"sourceCode":"        method: \"POST\",\n        body: JSON.stringify(waveCall),\n    });\n    const prtn = fetchPromise\n        .then((resp) => {\n            if (!resp.ok) {\n                throw new Error(`call ${methodName} failed: ${resp.status} ${resp.statusText}`);\n            }\n            return resp.json();\n        })\n        .then((respData: WebReturnType) => {\n            if (respData == null) {\n                return null;\n            }\n            if (respData.updates != null) {\n                updateWaveObjects(respData.updates);\n            }\n            if (respData.error != null) {\n                throw new Error(`call ${methodName} error: ${respData.error}`);\n            }\n            const durationStr = Date.now() - startTs + \"ms\";\n            debugLogBackendCall(methodName, durationStr, args);\n            return respData.data;\n        });\n    return prtn;\n}\n\nconst waveObjectValueCache = new Map<string, WaveObjectValue<any>>();\n\nfunction reloadWaveObject<T extends WaveObj>(oref: string): Promise<T> {\n    let wov = waveObjectValueCache.get(oref);\n    if (wov === undefined) {\n        wov = getWaveObjectValue<T>(oref, true);\n        return wov.pendingPromise;\n    }\n    const prtn = GetObject<T>(oref);\n    prtn.then((val) => {","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/frontend/app/store/wos.ts#L122-L158","documentation":"The backend call succeeded at the HTTP layer and returned valid JSON, but the WebReturnType payload carried an error field — an application-level error from the backend service handler (e.g. the requested object doesn't exist or the operation was refused). callBackendService re-throws it as a client-side Error prefixed with the method name.","triggerScenarios":"Any waveobj service call whose handler returns {error: \"...\"}: GetObject on a nonexistent oid, invalid arguments to a service method, backend business-rule rejection (permissions, state conflicts).","commonSituations":"Referencing a deleted waveobj (stale oid in frontend state); calling a service method with wrong argument shape/type; server-side validation rejecting the request; version mismatch where frontend sends args a new backend rejects.","solutions":["Read the message after the prefix — it contains the backend's own error text identifying the failing condition","Validate object ids / arguments before the call (existence checks, correct types)","Refresh frontend state if the object was deleted server-side","Check waveserver logs at the same timestamp for the handler's stack trace","Align frontend/backend versions if argument-shape mismatches appear after an upgrade"],"exampleFix":"// before\nconst obj = await rpcService.Call(ctx, \"waveobj\", \"GetObject\", otype, oid);\n// after\nlet obj = null;\ntry {\n    obj = await rpcService.Call(ctx, \"waveobj\", \"GetObject\", otype, oid);\n} catch (e) {\n    if (String(e).includes(\"waveobj.GetObject error\")) {\n        console.warn(\"object unavailable:\", e.message);\n        await refreshObjStore();\n    } else {\n        throw e;\n    }\n}","handlingStrategy":"try-catch","validationCode":"if (!oid || typeof oid !== \"string\") {\n    throw new Error(\"GetObject requires a valid oid\");\n}\n// optionally check object existence from local cache first","typeGuard":"function isBackendServiceError(err: unknown): err is Error {\n    return err instanceof Error && /call .* error: /.test(err.message);\n}","tryCatchPattern":"try {\n    const obj = await rpcService.Call(ctx, \"waveobj\", \"GetObject\", otype, oid);\n} catch (e) {\n    if (isBackendServiceError(e)) {\n        console.error(\"backend rejected call:\", e.message.replace(/^call \\S+ error: /, \"\"));\n        await refreshObjStore();\n        return null;\n    }\n    throw e;\n}","preventionTips":["Parse the backend message after the 'call X error:' prefix for root cause","Validate ids/args against the waveobj schema before calling","Refresh frontend state when objects are deleted server-side","Check waveserver logs for the handler stack trace and keep versions aligned"],"tags":["backend","rpc","application-error","wave"],"backgroundTag":"backend-service-error","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}