microsoft/typescript-go · error

invalid %s: got %v

Error message

invalid %s: got %v

What it means

Thrown when a value must decode into one of the generated union/alias types (e.g. IntegerOrString, StringOrMarkupContent, BooleanOrHoverOptions, the many XxxOrNull wrappers) but the JSON kind at the current position matches none of the union members. The generated decoders call errInvalidKind(typeName, dec.PeekKind()) after exhausting every case, so the message names the protocol type and the offending JSON kind.

Source

Thrown at internal/lsp/lsproto/lsp.go:100

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)
	}
}

func assertAtMostOne(message string, count int) {
	if count > 1 {

View on GitHub (pinned to 1bcfa18d79)

Solutions

  1. Check the type name in the message against the LSP metaModel and reshape the JSON to one of the permitted shapes (e.g. replace `true` with an options object, or a string with {kind, value} markup content).
  2. If the value can legitimately be absent, send null only if the type name ends in OrNull; otherwise omit the field entirely.
  3. In tests, build the value by marshaling the corresponding generated Go union struct so only valid shapes are produced.
  4. Regenerate lsproto from an updated meta model if the client legitimately sends a shape the current generated code predates.

Example fix

// before: boolean where object union is required
"hoverProvider": true
// after (when the generated type demands options)
"hoverProvider": {}
Defensive patterns

Strategy: type-guard

Validate before calling

// before sending a capability value, confirm its JSON kind matches the union
func kindOK(v any, allow ...string) bool {
    kind := reflect.KindOf(v) // map[string]any -> "object", []any -> "array", etc.
    return slices.Contains(allow, kind)
}

// e.g. DocumentSelectorOrNull takes array-or-null
if v != nil && !kindOK(v, "array") { return fmt.Errorf("bad selector") }

Type guard

func isObjectOrArray(v any) bool {
    switch v.(type) {
    case map[string]any, []any:
        return true
    }
    return false
}

Prevention

When it happens

Trigger: Sending a scalar where a union requires object/array, e.g. hover result as a bare string when only StringOrMarkupContent shapes are allowed, marking capabilities as true/false where the struct requires an object, null for XxxOrNull types whose null branch is only taken under exact kind matching, or an array where DocumentSelectorOrNull expects an object. Any params or result payload whose JSON kind does not satisfy the union's kind dispatch in lsp_generated.go.

Common situations: Clients implementing an older/newer LSP spec where a capability was boolean instead of object (or vice versa); hand-crafted JSON-RPC responses in tests; proxies that coerce types; sending null where the generated OrNull union still rejects it because the base type was not nullable in the meta model.

Related errors


AI-assisted analysis of microsoft/typescript-go@1bcfa18d79 (2026-08-16). Data as JSON: /api/errors/c2d07a68b3c86af6. Report an issue: GitHub.