microsoft/typescript-go · error
expected %s value %s, got %s
Error message
expected %s value %s, got %s
What it means
Signals that a JSON literal-enum type in the LSP schema (values declared as fixed string literals, like MarkupKind, TextDocumentSyncKind, DiagnosticSeverity, or CodeActionKind literals) received a value that is not one of the enumerated literals. The generated decoder tries each allowed literal and, on exhaustion, calls errLiteralMismatch(typeName, expected, got) naming the type, the expected literal, and the offending bytes.
Source
Thrown at internal/lsp/lsproto/lsp.go:108
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)
}
}
// jsonKeyCheck compares a raw JSON key token (including quotes) against a Go string.
func jsonKeyCheck(name []byte, key string) bool {
return len(name) == len(key)+2 && name[0] == '"' && string(name[1:len(name)-1]) == key
}View on GitHub (pinned to 1bcfa18d79)
Solutions
- Compare the `got` bytes in the error with the `expected` literal and correct the value to the exact enumerated literal from the LSP spec.
- Copy literal values from the corresponding lsproto constants (e.g. lsproto.MarkupKindMarkdown) rather than retyping strings.
- If a genuinely new literal is being rejected, regenerate lsp_generated.go from the updated meta model.
- Sanitize user-supplied enum strings at your config boundary before forwarding them into LSP messages.
Example fix
// before
{"contents":{"kind":"Markdown","value":"hi"}}
// after
{"contents":{"kind":"markdown","value":"hi"}} Defensive patterns
Strategy: type-guard
Validate before calling
// whitelist enum values before injecting user config into LSP messages
var markupKinds = map[string]bool{"plaintext": true, "markdown": true}
if !markupKinds[userSetting] {
return fmt.Errorf("invalid markup kind %q", userSetting)
} Type guard
func isValidEnum(v any, allowed map[string]bool) bool {
s, ok := v.(string)
return ok && allowed[s]
} Prevention
- Use exact lowercase literals from the LSP spec; enums are case-sensitive.
- Reference lsproto constants (e.g. lsproto.MarkupKindMarkdown) instead of retyping strings.
- Validate user-supplied enum strings at the settings boundary.
When it happens
Trigger: Sending "markupKind": "markdown" instead of "markdown" vs "plaintext" exact-match; setting severity as a string when an integer literal is required; a completion trigger kind outside the enum; any typo or case mismatch in an enum-valued field (LSP enums are case-sensitive).
Common situations: Typos or casing errors ("Markdown" vs "markdown") from hand-built payloads; version skew where a newer client sends a literal the server's generated enum does not know yet; config-driven injection of enum values from user settings without validation.
Related errors
AI-assisted analysis of microsoft/typescript-go@1bcfa18d79 (2026-08-16).
Data as JSON: /api/errors/1c1fa1a6f19520c9.
Report an issue: GitHub.