microsoft/typescript-go · error
invalid %s: %s
Error message
invalid %s: %s
What it means
The last-resort decode failure for polymorphic LSP types: after kind-based dispatch narrows the candidate members of a union (e.g. TextEditOrInsertReplaceEdit, WorkspaceFullDocumentDiagnosticReportOrUnchangedDocumentDiagnosticReport, WorkDoneProgressBeginOrReportOrEnd), each candidate is trial-unmarshaled; if all fail, errInvalidValue(typeName, data) reports the type name plus the raw JSON bytes. Unlike errInvalidKind this means the JSON kind was plausible but the contents did not satisfy any member.
Source
Thrown at internal/lsp/lsproto/lsp.go:104
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 {
panic(message)
}
}
View on GitHub (pinned to 1bcfa18d79)
Solutions
- Inspect the raw JSON echoed in the error and compare it against the member shapes of the named union in the LSP spec; fix the missing/invalid nested field (usually a missing `kind` or `range`).
- Add the discriminator the union dispatches on (e.g. "kind":"begin" for progress, "kind":"full" for diagnostic reports).
- Validate outbound payloads in tests by unmarshaling into the generated lsproto union type before sending.
Example fix
// before: diagnostic report without discriminator
{"resultId":"1","items":[]}
// after
{"kind":"full","resultId":"1","items":[]} Defensive patterns
Strategy: validation
Validate before calling
// ensure discriminator-bearing unions carry a known `kind`
var knownKinds = map[string]bool{"full": true, "unchanged": true}
func validReport(r map[string]any) bool {
k, _ := r["kind"].(string)
return knownKinds[k]
} Type guard
func hasKnownDiscriminator(v map[string]any, key string, allowed map[string]bool) bool {
s, ok := v[key].(string)
return ok && allowed[s]
} Prevention
- Always emit the `kind` discriminator on polymorphic LSP values (reports, progress, edits).
- Validate nested payloads against the generated union types in tests before shipping fixtures.
- Use the lsproto Go types to construct values so invalid members cannot be expressed.
When it happens
Trigger: A diagnostic report lacking its required kind discriminator; a TextEdit whose range is absent or malformed; a progress value whose kind is neither begin, report, nor end; a WorkspaceEdit with an unknown structure. Any payload that passes the kind check but fails every candidate's field validation in lsp_generated.go (errMissing/errNull inside trial unmarshals bubble up to this catch-all).
Common situations: Clients that omit discriminator fields like kind; stale code assuming a rename result shape from an older LSP version; AI-generated or hand-written JSON fixtures; middleware that drops nested required fields while transforming payloads.
Related errors
- missing required properties: %s
- invalid %s: got %v
- expected %s value %s, got %s
- -32602
- expected null, got %s
AI-assisted analysis of microsoft/typescript-go@1bcfa18d79 (2026-08-16).
Data as JSON: /api/errors/b42f5276e76a1cbb.
Report an issue: GitHub.