{"record":{"id":"2ccdafee47dac83a","repo":"charmbracelet/vhs","slug":"invalid-command-literal","errorCode":null,"errorMessage":"Invalid command: ${literal}","messagePattern":"Invalid command: (.+?)","errorType":"validation","errorClass":"parser.Error","httpStatus":null,"severity":"error","filePath":"parser/parser.go","lineNumber":189,"sourceCode":"\t\treturn []Command{p.parseHide()}\n\tcase token.REQUIRE:\n\t\treturn []Command{p.parseRequire()}\n\tcase token.SHOW:\n\t\treturn []Command{p.parseShow()}\n\tcase token.WAIT:\n\t\treturn []Command{p.parseWait()}\n\tcase token.SOURCE:\n\t\treturn p.parseSource()\n\tcase token.SCREENSHOT:\n\t\treturn []Command{p.parseScreenshot()}\n\tcase token.COPY:\n\t\treturn []Command{p.parseCopy()}\n\tcase token.PASTE:\n\t\treturn []Command{p.parsePaste()}\n\tcase token.ENV:\n\t\treturn []Command{p.parseEnv()}\n\tdefault:\n\t\tp.errors = append(p.errors, NewError(p.cur, \"Invalid command: \"+p.cur.Literal))\n\t\treturn []Command{{Type: token.ILLEGAL}}\n\t}\n}\n\nfunc (p *Parser) parseWait() Command {\n\tcmd := Command{Type: token.WAIT}\n\n\tif p.peek.Type == token.PLUS {\n\t\tp.nextToken()\n\t\tif p.peek.Type != token.STRING || (p.peek.Literal != \"Line\" && p.peek.Literal != \"Screen\") {\n\t\t\tp.errors = append(p.errors, NewError(p.peek, \"Wait+ expects Line or Screen\"))\n\t\t\treturn cmd\n\t\t}\n\t\tcmd.Args = p.peek.Literal\n\t\tp.nextToken()\n\t} else {\n\t\tcmd.Args = \"Line\"\n\t}","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/charmbracelet/vhs/blob/c073383b5de0b1f57bf514113029c306bc986539/parser/parser.go#L171-L207","documentation":"In vhs (charmbracelet/vhs), a .tape file is a sequence of commands (Type, Copy, Paste, Env, Wait, Sleep, etc.). parseCommand dispatches on the current token's type, and when it sees a token that maps to no known command it records this error and returns an ILLEGAL command so parsing can continue. It means the parser encountered a word at a command position that is not one of vhs's built-in commands.","triggerScenarios":"The first word of a line in a .tape file is not a registered token/command, e.g. a typo like 'Tyep foo' or 'Prtscr', or an unsupported/renamed command, or stray text pasted into the tape file.","commonSituations":"Typos in command names; copying commands from old vhs examples that were renamed between versions; leaving prose or shell text directly in a .tape file instead of inside Output/Comment or $ shell commands; using commands from a fork or newer vhs release than the installed binary.","solutions":["Check the command name spelling against the vhs command list (Type, Enter, Space, Ctrl, Alt, Shift, Sleep, Wait, Set, Output, Hide, Show, Screenshot, Copy, Paste, Env, Tab, Backspace, Delete, Down, Up, etc.).","If the line is meant to be a comment, prefix it with '#' or wrap it in a Comment block.","If it is meant to be a shell command, prefix it with '$' (e.g. '$ echo hello').","Run 'vhs' with your tape via a recent version; update vhs if the command exists in newer releases."],"exampleFix":"// before (.tape)\nTyep \"hello\"\n// after (.tape)\nType \"hello\"","handlingStrategy":"validation","validationCode":"var validCommands = map[string]bool{\"Type\":true,\"Enter\":true,\"Space\":true,\"Tab\":true,\"Backspace\":true,\"Delete\":true,\"Up\":true,\"Down\":true,\"Left\":true,\"Right\":true,\"Sleep\":true,\"Wait\":true,\"Set\":true,\"Output\":true,\"Hide\":true,\"Show\":true,\"Screenshot\":true,\"Copy\":true,\"Paste\":true,\"Env\":true,\"Ctrl\":true,\"Alt\":true,\"Shift\":true,\"Source\":true,\"Require\":true}\nfunc isValidTapeCommand(word string) bool { return validCommands[word] }","typeGuard":"func isKnownCommand(tok string) bool { _, ok := token.Keywords[tok]; return ok }","tryCatchPattern":null,"preventionTips":["Spell-check command names against the vhs README command table","Prefix commentary lines with '#' and shell commands with '$'","Pin and update your vhs version; check release notes for renamed commands","Run 'vhs yourfile.tape' early in CI to catch parse errors before recording"],"tags":["parser","tape-file","invalid-command"],"backgroundTag":"unknown-command","analyzedSha":"c073383b5de0b1f57bf514113029c306bc986539","analyzedAt":"2026-09-02T01:53:05.682Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}