{"record":{"id":"818411d4dde3f0ce","repo":"charmbracelet/vhs","slug":"expected-alt-character-got-literal","errorCode":null,"errorMessage":"Expected alt character, got ${literal}","messagePattern":"Expected alt character, got (.+?)","errorType":"validation","errorClass":"parser.Error","httpStatus":null,"severity":"error","filePath":"parser/parser.go","lineNumber":372,"sourceCode":"// parseAlt parses an alt command.\n// An alt command takes a character to type while the modifier is held down.\n//\n//\tAlt+<character>\nfunc (p *Parser) parseAlt() Command {\n\tif p.peek.Type == token.PLUS {\n\t\tp.nextToken()\n\t\tif p.peek.Type == token.STRING ||\n\t\t\tp.peek.Type == token.ENTER ||\n\t\t\tp.peek.Type == token.LEFT_BRACKET ||\n\t\t\tp.peek.Type == token.RIGHT_BRACKET ||\n\t\t\tp.peek.Type == token.TAB {\n\t\t\tc := p.peek.Literal\n\t\t\tp.nextToken()\n\t\t\treturn Command{Type: token.ALT, Args: c}\n\t\t}\n\t}\n\n\tp.errors = append(p.errors, NewError(p.cur, \"Expected alt character, got \"+p.cur.Literal))\n\treturn Command{Type: token.ALT}\n}\n\n// parseShift parses a shift command.\n// A shift command takes one character and types while shift is held down.\n//\n//\tShift+<char>\n//\tE.g.\n//\tShift+A\n//\tShift+Tab\n//\tShift+Enter\nfunc (p *Parser) parseShift() Command {\n\tif p.peek.Type == token.PLUS {\n\t\tp.nextToken()\n\t\tif p.peek.Type == token.STRING ||\n\t\t\tp.peek.Type == token.ENTER ||\n\t\t\tp.peek.Type == token.LEFT_BRACKET ||\n\t\t\tp.peek.Type == token.RIGHT_BRACKET ||","sourceCodeStart":354,"sourceCodeEnd":390,"githubUrl":"https://github.com/charmbracelet/vhs/blob/c073383b5de0b1f57bf514113029c306bc986539/parser/parser.go#L354-L390","documentation":"Alt in vhs takes exactly one argument: a single character (or valid key) to press with Alt held, e.g. 'Alt+b'. parseAlt walks the following tokens; if none yields an acceptable argument it records this error naming the token it stopped at and returns an ALT command with no Args.","triggerScenarios":"'Alt' with no argument ('Alt' alone or 'Alt+' at end of line), or an argument that is not a single character / valid key token.","commonSituations":"Writing multi-character sequences after Alt ('Alt+foo'); leaving a dangling 'Alt+' after deleting the key; confusing Alt with Ctrl chains.","solutions":["Give Alt exactly one character: 'Alt+b', 'Alt+x'.","For key-combos with modifiers use the Ctrl chain syntax (e.g. 'Ctrl+Alt+...') only with supported keys.","Remove the Alt line if it was accidental."],"exampleFix":"// before (.tape)\nAlt+foo\n// after (.tape)\nAlt+f","handlingStrategy":"validation","validationCode":"func validAltArg(a string) bool { return len(a) == 1 }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Give Alt exactly one character argument","Avoid multi-character tokens after Alt; that syntax belongs to Ctrl chains","Delete dangling 'Alt+' remnants when editing tapes"],"tags":["parser","alt-command","missing-argument"],"backgroundTag":"invalid-key-combination","analyzedSha":"c073383b5de0b1f57bf514113029c306bc986539","analyzedAt":"2026-09-02T01:53:05.682Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}