charmbracelet/vhs · error · parser.Error
Invalid control argument: ${literal}
Error message
Invalid control argument: ${literal} What it means
Emitted together with 'Not a valid modifier' whenever a Ctrl argument fails the accepted-key check (modifiers, known keyword keys, or single-character strings). It names the offending literal so the user can see exactly which argument was rejected.
Source
Thrown at parser/parser.go:340
peek.Type == token.SPACE,
peek.Type == token.BACKSPACE,
peek.Type == token.MINUS,
peek.Type == token.AT,
peek.Type == token.LEFT_BRACKET,
peek.Type == token.RIGHT_BRACKET,
peek.Type == token.CARET,
peek.Type == token.BACKSLASH,
peek.Type == token.LEFT,
peek.Type == token.RIGHT,
peek.Type == token.UP,
peek.Type == token.DOWN,
peek.Type == token.STRING && len(peek.Literal) == 1:
args = append(args, peek.Literal)
default:
// Key arguments with len > 1 are not valid
p.errors = append(p.errors,
NewError(p.cur, "Not a valid modifier"),
NewError(p.cur, "Invalid control argument: "+p.cur.Literal))
}
p.nextToken()
}
if len(args) == 0 {
p.errors = append(p.errors, NewError(p.cur, "Expected control character with args, got "+p.cur.Literal))
}
ctrlArgs := strings.Join(args, " ")
return Command{Type: token.CTRL, Args: ctrlArgs}
}
// parseAlt parses an alt command.
// An alt command takes a character to type while the modifier is held down.
//
// Alt+<character>
func (p *Parser) parseAlt() Command {View on GitHub (pinned to c073383b5d)
Solutions
- Replace the named invalid argument with a supported key or a single character.
- Consult the vhs docs (Type/Ctrl reference) for the supported key list.
- Lowercase/uppercase the key to match vhs's keyword spelling.
Example fix
// before (.tape) Ctrl+enter // after (.tape) Ctrl+Enter
Defensive patterns
Strategy: validation
Validate before calling
func validCtrlArg(a string) bool { if len(a) == 1 { return true }; _, ok := token.Keywords[a]; return ok } Prevention
- Copy key names from the official vhs documentation rather than memory
- Watch for both errors ('Not a valid modifier' + 'Invalid control argument') pointing at the same bad token
- Test each Ctrl line incrementally when writing tapes
When it happens
Trigger: Same as error 6: a token in the Ctrl argument list that is not a modifier, not a known keyword key, and not a single-character string — 'Ctrl+foo', 'Ctrl+enter', 'Ctrl+Home' (if unsupported).
Common situations: Unsupported key names; case mismatches against token.Keywords; typos in single-character args.
Related errors
- Not a valid modifier
- Wait+ expects Line or Screen
- Modifiers must come before other characters
- Expected control character with args, got ${literal}
- Invalid command: ${literal}
AI-assisted analysis of charmbracelet/vhs@c073383b5d (2026-09-02).
Data as JSON: /api/errors/4d1d0f6cd68000e1.
Report an issue: GitHub.