{"record":{"id":"365d0f788748b2d9","repo":"wavetermdev/waveterm","slug":"error-re-marshalling-command-data-w","errorCode":null,"errorMessage":"error re-marshalling command data: %w","messagePattern":"error re-marshalling command data: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/wshutil/wshadapter.go","lineNumber":69,"sourceCode":"\nfunc noImplHandler(handler *RpcResponseHandler) bool {\n\thandler.SendResponseError(fmt.Errorf(\"command %q not implemented\", handler.GetCommand()))\n\treturn true\n}\n\nfunc recodeCommandData(command string, data any, commandDataType reflect.Type) (any, error) {\n\tif command == \"\" || commandDataType == nil {\n\t\treturn data, nil\n\t}\n\tmethodDecl := WshCommandDeclMap[command]\n\tif methodDecl == nil {\n\t\treturn data, fmt.Errorf(\"command %q not found\", command)\n\t}\n\tcommandDataPtr := reflect.New(commandDataType).Interface()\n\tif data != nil {\n\t\terr := utilfn.ReUnmarshal(commandDataPtr, data)\n\t\tif err != nil {\n\t\t\treturn data, fmt.Errorf(\"error re-marshalling command data: %w\", err)\n\t\t}\n\t}\n\treturn reflect.ValueOf(commandDataPtr).Elem().Interface(), nil\n}\n\nfunc serverImplAdapter(impl any) func(*RpcResponseHandler) bool {\n\tif impl == nil {\n\t\treturn noImplHandler\n\t}\n\trtype := reflect.TypeOf(impl)\n\tif rtype.Kind() != reflect.Ptr && rtype.Elem().Kind() != reflect.Struct {\n\t\tpanic(fmt.Sprintf(\"expected struct pointer, got %s\", rtype))\n\t}\n\t// returns isAsync\n\treturn func(handler *RpcResponseHandler) bool {\n\t\tcmd := handler.GetCommand()\n\t\tmethodDecl := WshCommandDeclMap[cmd]\n\t\tif methodDecl == nil {","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/wshutil/wshadapter.go#L51-L87","documentation":"After resolving the command's declared type, recodeCommandData round-trips the payload (utilfn.ReUnmarshal: marshal to JSON then unmarshal into the declared type pointer). If the payload cannot be converted into the declared command data type, this wrapped error is returned. It is a payload-shape mismatch, not a transport failure.","triggerScenarios":"Calling an RPC with data whose JSON shape does not fit the command's declared data struct: wrong field names (Go unmarshal is case-insensitive but incompatible types fail), a string where a number is expected, an object where an array is expected, or data that is not JSON-marshalable.","commonSituations":"Sending a bare value when the command expects a struct like CommandVarData; version skew where a field's type changed between releases; scripts passing shell-style strings to typed commands.","solutions":["Read the wrapped inner error to see which JSON field/type failed, then reshape your payload to match the command's declared data struct in pkg/wshrpc.","Construct the proper typed struct (e.g. wshrpc.CommandVarData{...}) instead of an ad-hoc map or string.","If both sides are your code, update the client and server together so the payload schema matches the declaration."],"exampleFix":"// before: string payload for a struct command\ndata := \"/home/user/.zshrc\"\n// after: typed payload\npath, _ := homedir.ExpandHome(\"~/.zshrc\")\ndata := wshrpc.CommandFileData{Info: &wshrpc.FileInfo{Path: path}}","handlingStrategy":"type-guard","validationCode":"// Validate payload marshals and fits the declared struct before sending\nb, err := json.Marshal(payload)\nif err != nil { return err }\ntyped := wshrpc.CommandVarData{}\nif err := json.Unmarshal(b, &typed); err != nil {\n    return fmt.Errorf(\"payload does not match declared type: %w\", err)\n}","typeGuard":"func isCommandData[T any](data any) bool {\n    var zero T\n    b, err := json.Marshal(data)\n    if err != nil { return false }\n    return json.Unmarshal(b, &zero) == nil\n}","tryCatchPattern":"_, err := client.SendRpcRequest(ctx, cmd, data)\nvar reErr *fmt.Errorf\nif err != nil && errors.As(err, &reErr) && strings.Contains(err.Error(), \"re-marshalling command data\") {\n    log.Printf(\"payload shape mismatch for %s: %v\", cmd, err)\n    return fmt.Errorf(\"invalid payload for %s: %w\", cmd, err)\n}","preventionTips":["Build payloads from the typed structs in pkg/wshrpc instead of raw maps.","Round-trip test payloads (marshal/unmarshal into the declared type) in unit tests.","Read the wrapped %w error — it names the exact JSON field that failed."],"tags":["rpc","wsh","json","payload","waveterm"],"backgroundTag":"rpc-payload-marshal-failed","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}