microsoft/typescript-go · error
missing required properties: %s
Error message
missing required properties: %s
What it means
Thrown by the lsproto struct decoder when an inbound JSON-RPC message's params object decodes successfully but is missing one or more fields the LSP spec marks required. This is the code-generated TypeScript-Go LSP server's strict validation: every struct field tagged required in lsp_generated.go must appear in the payload, or UnmarshalParams / json.Unmarshal fails with this error before dispatch.
Source
Thrown at internal/lsp/lsproto/lsp.go:96
type HasLocation interface {
GetLocation() Location
}
type URI string // !!!
type Method string
func errNotObject(k json.Kind) error {
return fmt.Errorf("expected object start, but encountered %v", k)
}
func errNull(field string) error {
return fmt.Errorf("null value is not allowed for field %q", field)
}
func errMissing(props []string) error {
return fmt.Errorf("missing required properties: %s", strings.Join(props, ", "))
}
func errInvalidKind(typeName string, got json.Kind) error {
return fmt.Errorf("invalid %s: got %v", typeName, got)
}
func errInvalidValue(typeName string, data []byte) error {
return fmt.Errorf("invalid %s: %s", typeName, data)
}
func errLiteralMismatch(typeName string, expected string, got []byte) error {
return fmt.Errorf("expected %s value %s, got %s", typeName, expected, got)
}
func assertOnlyOne(message string, count int) {
if count != 1 {
panic(message)
}View on GitHub (pinned to 1bcfa18d79)
Solutions
- Diff the sent params against the LSP spec for that method and add every field named in the error message (the error lists exactly which properties are missing).
- If the sender is your own code, serialize from the corresponding lsproto struct (e.g. *lsproto.DidOpenTextDocumentParams) instead of hand-writing JSON, so required fields cannot be dropped.
- If you control the receiving side and the field is genuinely optional in your dialect, regenerate/adjust the struct tags in _generate/generate.mts so the field is not required, then rerun the generator.
- For test fixtures, round-trip them through json.Marshal of the lsproto params type to validate they are complete.
Example fix
// before (client sends incomplete params)
{"jsonrpc":"2.0","id":1,"method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///a.ts","languageId":"typescript"}}}
// after: include required `version` and `text`
{"jsonrpc":"2.0","id":1,"method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///a.ts","languageId":"typescript","version":1,"text":"const x = 1;"}}} Defensive patterns
Strategy: validation
Validate before calling
// client-side: assert params contain every required field before sending
func checkRequired(obj map[string]any, required ...string) error {
var missing []string
for _, k := range required {
if _, ok := obj[k]; !ok {
missing = append(missing, k)
}
}
if len(missing) > 0 {
return fmt.Errorf("missing required properties: %s", strings.Join(missing, ", "))
}
return nil
}
err := checkRequired(renameParams, "textDocument", "position", "newName") Type guard
func hasAllRequired(params map[string]any, required []string) bool {
for _, k := range required {
if _, ok := params[k]; !ok {
return false
}
}
return true
} Prevention
- Build request params by marshaling the generated lsproto structs instead of hand-writing JSON maps.
- Validate fixtures by unmarshaling them into the target lsproto params type in unit tests.
- Keep the LSP meta model version in sync between client templates and the generated server code.
When it happens
Trigger: A client sends a request or notification whose params omit a required field, e.g. textDocument/didOpen without textDocument, textDocument/rename without newName, or initialize without capabilities or rootUri/workspaceFolders. Concretely, structcodec.go:113-121 computes requiredMask &^ seen; any unlisted required field produces errMissing. It also fires when a hand-rolled JSON-RPC client or test fixture forgets a field the spec mandates.
Common situations: Custom editor integrations or test harnesses that build params by hand; clients targeting an older LSP spec revision where a field was optional; buggy proxies that strip fields; unit tests with hand-written JSON that drifted from the generated struct tags after a protocol regeneration.
Related errors
AI-assisted analysis of microsoft/typescript-go@1bcfa18d79 (2026-08-16).
Data as JSON: /api/errors/d76d61d0e4e14f70.
Report an issue: GitHub.