{"record":{"id":"8655da31aee82606","repo":"wavetermdev/waveterm","slug":"cannot-convert-t-to-s-key-s-error-v","errorCode":null,"errorMessage":"cannot convert %T to %s (key %s) error: %v","messagePattern":"cannot convert %T to (.+?) \\(key (.+?)\\) error: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/service/service.go","lineNumber":162,"sourceCode":"\t\t\t\treturn nil, fmt.Errorf(\"cannot convert %T to %s (idx %d) error: %v\", jsonArg, waveObjSliceRType, idx, err)\n\t\t\t}\n\t\t\tnativeSlice[idx] = nativeObj\n\t\t}\n\t\treturn nativeSlice, nil\n\t} else if argType == waveObjMapRType {\n\t\tif jsonType.Kind() != reflect.Map {\n\t\t\treturn nil, fmt.Errorf(\"cannot convert %T to %s\", jsonArg, argType)\n\t\t}\n\t\tmapArg := jsonArg.(map[string]any)\n\t\tnativeMap := make(map[string]waveobj.WaveObj)\n\t\tfor key, elem := range mapArg {\n\t\t\telemMap, ok := elem.(map[string]any)\n\t\t\tif !ok {\n\t\t\t\treturn nil, fmt.Errorf(\"cannot convert %T to %s (key %s is not a map, is %T)\", jsonArg, waveObjMapRType, key, elem)\n\t\t\t}\n\t\t\tnativeObj, err := waveobj.FromJsonMap(elemMap)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"cannot convert %T to %s (key %s) error: %v\", jsonArg, waveObjMapRType, key, err)\n\t\t\t}\n\t\t\tnativeMap[key] = nativeObj\n\t\t}\n\t\treturn nativeMap, nil\n\t} else {\n\t\treturn nil, fmt.Errorf(\"invalid special wave argument type %s\", argType)\n\t}\n}\n\nfunc convertSpecialForReturn(argType reflect.Type, nativeArg any) (any, error) {\n\tif argType == waveObjRType {\n\t\treturn waveobj.ToJsonMap(nativeArg.(waveobj.WaveObj))\n\t} else if argType == waveObjSliceRType {\n\t\tnativeSlice := nativeArg.([]waveobj.WaveObj)\n\t\tjsonSlice := make([]map[string]any, len(nativeSlice))\n\t\tfor idx, elem := range nativeSlice {\n\t\t\telemMap, err := waveobj.ToJsonMap(elem)\n\t\t\tif err != nil {","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/service/service.go#L144-L180","documentation":"For map[string]waveobj.WaveObj arguments, each map value that passes the object check is decoded with waveobj.FromJsonMap. If decoding fails for any value (missing otype/oid, unknown otype, invalid fields), the whole call fails with this error, which names the failing key and wraps the underlying FromJsonMap error.","triggerScenarios":"An RPC call with a WaveObj map argument where the value at some key is an object but malformed: absent \"otype\"/\"oid\", an otype the server doesn't know, or fields failing otype-specific validation.","commonSituations":"Partially constructed objects placed into maps; an otype introduced in a newer client unknown to an older backend; field renames after a schema migration leaving payloads invalid.","solutions":["Read the wrapped inner error and fix the WaveObj stored under the reported key (usually missing/invalid otype or oid).","Ensure every map value carries valid \"otype\" and \"oid\" for a registered WaveObj type.","Synchronize client and server versions so otype names and field schemas match.","Build payloads with the SDK serialization helpers (ToJsonMap) instead of hand-assembling maps."],"exampleFix":"// before\ncallService(\"objservice\", \"SetObjects\", { \"main\": { \"otype\": \"tab\" } }) // missing oid\n// after\ncallService(\"objservice\", \"SetObjects\", { \"main\": { \"otype\": \"tab\", \"oid\": \"xyz789\", \"meta\": {} } })","handlingStrategy":"validation","validationCode":"for (const [k, v] of Object.entries(arg)) { if (typeof v?.otype !== 'string' || typeof v?.oid !== 'string') throw new Error('map value at key ' + k + ' missing valid otype/oid'); }","typeGuard":"function isValidWaveObj(v) { return v && typeof v.otype === 'string' && typeof v.oid === 'string'; }","tryCatchPattern":"try { return await callService(svc, method, arg); } catch (e) { const m = String(e).match(/key (\\S+)\\) error: (.*)$/); if (m) { console.error('WaveObj at key ' + m[1] + ' failed decode: ' + m[2]); } throw e; }","preventionTips":["Ensure every map value has valid otype/oid recognized by the server.","Use SDK serialization instead of hand-built object maps.","Version-align otype schemas between client and server.","Log the wrapped inner error to pinpoint the malformed key."],"tags":["rpc","deserialization","waveobj","validation"],"backgroundTag":"schema-validation-failed","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}