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

  1. Compare the `got` bytes in the error with the `expected` literal and correct the value to the exact enumerated literal from the LSP spec.
  2. Copy literal values from the corresponding lsproto constants (e.g. lsproto.MarkupKindMarkdown) rather than retyping strings.
  3. If a genuinely new literal is being rejected, regenerate lsp_generated.go from the updated meta model.
  4. 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

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.