grpc-ecosystem/grpc-gateway · error

expected but got

Error message

expected %q but got %q

What it means

Token-mismatch error from parser.accept: the next token in the path template did not equal the expected literal terminal (one of '/', '*', '**', '.', '=', '{', '}'). Note accept also tolerates '/' as a stand-in for any expected literal separator; anything else triggers this error naming the expected and actual tokens.

Solutions

  1. Fix the HttpRule path template so the expected separator character appears where the parser needs it.
  2. Check for missing '/', '=', or braces and for typos in the template.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at internal/httprule/parse.go:252 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of grpc-ecosystem/grpc-gateway@a58a4436a3 (2026-09-02). Data as JSON: /api/errors/52f4e7dd3ccca864. Report an issue: GitHub.

Appendix: source

Thrown at internal/httprule/parse.go:252

// You can also use "/", "*", "**", "." or "=" as valid values.
const (
	typeIdent   = termType("ident")
	typeLiteral = termType("literal")
	typeEOF     = termType("$")
)

// eof is the terminal symbol which always appears at the end of token sequence.
const eof = "\u0000"

// accept tries to accept a token in "p".
// This function consumes a token and returns it if it matches to the specified "term".
// If it doesn't match, the function does not consume any tokens and return an error.
func (p *parser) accept(term termType) (string, error) {
	t := p.tokens[0]
	switch term {
	case "/", "*", "**", ".", "=", "{", "}":
		if t != string(term) && t != "/" {
			return "", fmt.Errorf("expected %q but got %q", term, t)
		}
	case typeEOF:
		if t != eof {
			return "", fmt.Errorf("expected EOF but got %q", t)
		}
	case typeIdent:
		if err := expectIdent(t); err != nil {
			return "", err
		}
	case typeLiteral:
		if err := expectPChars(t); err != nil {
			return "", err
		}
	default:
		return "", fmt.Errorf("unknown termType %q", term)
	}
	p.tokens = p.tokens[1:]
	p.accepted = append(p.accepted, t)

View on GitHub (pinned to a58a4436a3)