charmbracelet/vhs · error · parser.Error

Expected shift character, got ${literal}

Error message

Expected shift character, got ${literal}

What it means

Fires in parseShift when a Shift command is not followed by a valid combined key. The parser requires the literal form Shift+<key> where <key> is a string, Enter, Tab, '[' or ']'; any other token after the '+' (or a missing '+' entirely) fails the whitelist and the error is appended to p.errors.

Source

Thrown at parser/parser.go:398

//	E.g.
//	Shift+A
//	Shift+Tab
//	Shift+Enter
func (p *Parser) parseShift() Command {
	if p.peek.Type == token.PLUS {
		p.nextToken()
		if p.peek.Type == token.STRING ||
			p.peek.Type == token.ENTER ||
			p.peek.Type == token.LEFT_BRACKET ||
			p.peek.Type == token.RIGHT_BRACKET ||
			p.peek.Type == token.TAB {
			c := p.peek.Literal
			p.nextToken()
			return Command{Type: token.SHIFT, Args: c}
		}
	}

	p.errors = append(p.errors, NewError(p.cur, "Expected shift character, got "+p.cur.Literal))
	return Command{Type: token.SHIFT}
}

// parseKeypress parses a repeatable and time adjustable keypress command.
// A keypress command takes an optional typing speed and optional count.
//
//	Key[@<time>] [count]
func (p *Parser) parseKeypress(ct token.Type) Command {
	cmd := Command{Type: CommandType(ct)}
	cmd.Options = p.parseSpeed()
	cmd.Args = p.parseRepeat()
	return cmd
}

// parseOutput parses an output command.
// An output command takes a file path to which to output.
//
//	Output <path>

View on GitHub (pinned to c073383b5d)

Solutions

  1. Write the shift combination as Shift+X with a plus sign and a supported key (e.g. Shift+a, Shift+Tab, Shift+Enter, Shift+[)
  2. Quote the character as a string literal if the lexer does not recognize it, e.g. Shift+"a"
  3. Use the plain Key command instead if the intended key is not shift-combinable
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at parser/parser.go:398 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of charmbracelet/vhs@c073383b5d (2026-09-02). Data as JSON: /api/errors/41b54a4715dab1ce. Report an issue: GitHub.