{"record":{"id":"fda5ebe251b6cfa3","repo":"microsoft/typescript-go","slug":"w-w","errorCode":null,"errorMessage":"%w: %w","messagePattern":"%w: %w","errorType":"validation","errorClass":"ErrInvalidRequest","httpStatus":400,"severity":"error","filePath":"internal/api/session.go","lineNumber":596,"sourceCode":"}\n\n// HandleRequest implements Handler.\nfunc (s *Session) HandleRequest(ctx context.Context, method string, params json.Value) (any, error) {\n\t// Handle simple methods that don't need param parsing\n\tswitch method {\n\tcase \"echo\":\n\t\t// Return raw binary for msgpack protocol compatibility\n\t\tif s.useBinaryResponses {\n\t\t\treturn RawBinary(params), nil\n\t\t}\n\t\treturn params, nil\n\tcase \"ping\":\n\t\treturn \"pong\", nil\n\t}\n\n\tparsed, err := unmarshalPayload(method, params)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: %w\", ErrInvalidRequest, err)\n\t}\n\n\tswitch method {\n\tcase string(MethodRelease):\n\t\treturn s.handleRelease(ctx, parsed.(*ReleaseParams))\n\tcase string(MethodInitialize):\n\t\treturn s.handleInitialize(ctx)\n\tcase string(MethodUpdateSnapshot):\n\t\treturn s.handleUpdateSnapshot(ctx, parsed.(*UpdateSnapshotParams))\n\tcase string(MethodUpdateTemporarySnapshot):\n\t\treturn s.handleUpdateTemporarySnapshot(ctx, parsed.(*UpdateTemporarySnapshotParams))\n\tcase string(MethodParseCommandLine):\n\t\treturn s.handleParseCommandLine(ctx, parsed.(*ParseCommandLineParams))\n\tcase string(MethodReadConfigFile):\n\t\treturn s.handleReadConfigFile(ctx, parsed.(*ReadConfigFileParams))\n\tcase string(MethodParseJsonConfigFile):\n\t\treturn s.handleParseJsonConfigFileContent(ctx, parsed.(*ParseJsonConfigFileContentParams))\n\tcase string(MethodParseConfigFile):","sourceCodeStart":578,"sourceCodeEnd":614,"githubUrl":"https://github.com/microsoft/typescript-go/blob/1bcfa18d79a3be41772223d5c05dfe4480e614ff/internal/api/session.go#L578-L614","documentation":"HandleRequest could not decode the params payload into the struct registered for the method, and the decode error is wrapped in ErrInvalidRequest (\"api: invalid request\"). Each method in proto.go's unmarshalers map has exactly one params type (e.g. ProfileParams, GetSymbolAtPositionParams); the JSON or msgpack payload must match its field names and types. DocumentIdentifier additionally only accepts a plain string or an object with a uri field.","triggerScenarios":"Sending snapshot as a string instead of a number; passing a non-string/non-{uri} value for a file field (DocumentIdentifier's unmarshaler rejects other JSON kinds); sending an array instead of an object; a wrong-typed field such as positions: \"5\"; malformed JSON produced by hand-rolled request building.","commonSituations":"Version skew between client and server protocol structs after an upgrade; hand-written JSON payloads with typos in field names; msgpack encoders that emit a different shape than the decoder expects; copying a params body from a different method.","solutions":["Build the request from the generated params structs in internal/api (proto.go) instead of hand-writing JSON","Diff your payload field-by-field against the params struct for that exact method in proto.go","If client and server come from different typescript-go versions, align them to the same commit/version"],"exampleFix":"// before\nparams := map[string]any{\"snapshot\": \"42\", \"file\": 1337} // wrong types\n\n// after\nparams := api.GetSymbolAtPositionParams{Snapshot: 42, Project: projID, File: api.DocumentIdentifier{FileName: \"/abs/a.ts\"}, Position: 10}","handlingStrategy":"validation","validationCode":"// Marshal through the real params struct before sending; this proves the shape decodes.\nif _, err := json.Marshal(params); err != nil { return err }\n// For strict checking, round-trip: marshal then unmarshal into the same struct.\nblob, _ := json.Marshal(params)\nvar probe api.GetSymbolAtPositionParams\nif err := json.Unmarshal(blob, &probe); err != nil { return fmt.Errorf(\"bad payload: %w\", err) }","typeGuard":null,"tryCatchPattern":"if err != nil {\n    if errors.Is(err, api.ErrInvalidRequest) {\n        // payload shape mismatch for this method: log method + params and fix the client serializer\n    }\n    return err\n}","preventionTips":["Generate request payloads from the proto.go structs rather than hand-writing JSON","Pin client and server to the same typescript-go version so param structs cannot drift","Add a contract test that round-trips every request you send through UnmarshalJSONFrom"],"tags":["serialization","json","msgpack","validation","api"],"backgroundTag":null,"analyzedSha":"1bcfa18d79a3be41772223d5c05dfe4480e614ff","analyzedAt":"2026-08-16T02:12:00.115Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}