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

  1. 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).
  2. 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.
  3. 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.
  4. 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

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.