{"record":{"id":"687a39abfbcc5761","repo":"charmbracelet/vhs","slug":"not-a-valid-modifier","errorCode":null,"errorMessage":"Not a valid modifier","messagePattern":"Not a valid modifier","errorType":"validation","errorClass":"parser.Error","httpStatus":null,"severity":"error","filePath":"parser/parser.go","lineNumber":339,"sourceCode":"\t\tcase peek.Type == token.ENTER,\n\t\t\tpeek.Type == token.SPACE,\n\t\t\tpeek.Type == token.BACKSPACE,\n\t\t\tpeek.Type == token.MINUS,\n\t\t\tpeek.Type == token.AT,\n\t\t\tpeek.Type == token.LEFT_BRACKET,\n\t\t\tpeek.Type == token.RIGHT_BRACKET,\n\t\t\tpeek.Type == token.CARET,\n\t\t\tpeek.Type == token.BACKSLASH,\n\t\t\tpeek.Type == token.LEFT,\n\t\t\tpeek.Type == token.RIGHT,\n\t\t\tpeek.Type == token.UP,\n\t\t\tpeek.Type == token.DOWN,\n\t\t\tpeek.Type == token.STRING && len(peek.Literal) == 1:\n\t\t\targs = append(args, peek.Literal)\n\t\tdefault:\n\t\t\t// Key arguments with len > 1 are not valid\n\t\t\tp.errors = append(p.errors,\n\t\t\t\tNewError(p.cur, \"Not a valid modifier\"),\n\t\t\t\tNewError(p.cur, \"Invalid control argument: \"+p.cur.Literal))\n\t\t}\n\n\t\tp.nextToken()\n\t}\n\n\tif len(args) == 0 {\n\t\tp.errors = append(p.errors, NewError(p.cur, \"Expected control character with args, got \"+p.cur.Literal))\n\t}\n\n\tctrlArgs := strings.Join(args, \" \")\n\treturn Command{Type: token.CTRL, Args: ctrlArgs}\n}\n\n// parseAlt parses an alt command.\n// An alt command takes a character to type while the modifier is held down.\n//\n//\tAlt+<character>","sourceCodeStart":321,"sourceCodeEnd":357,"githubUrl":"https://github.com/charmbracelet/vhs/blob/c073383b5de0b1f57bf514113029c306bc986539/parser/parser.go#L321-L357","documentation":"When parsing a Ctrl command's arguments, vhs only accepts modifiers and single keys: keyword keys (Enter, Space, Tab, arrows like Up/Down), or single-character strings. Any other token — notably a string longer than one character that is not a known key — produces this error, immediately followed by 'Invalid control argument: <literal>'.","triggerScenarios":"A Ctrl argument is a multi-character string that is not a registered key keyword, e.g. 'Ctrl+abc', 'Ctrl+enter' (lowercase, not a keyword), or 'Ctrl+F12' if that key is not in token.Keywords.","commonSituations":"Lowercasing key names ('ctrl+enter' when keywords are case-sensitive); trying key names vhs does not define; pasting combos from other tools' syntax.","solutions":["Use valid key names from vhs's keys list (Enter, Space, Tab, Backspace, Delete, Up, Down, Left, Right, PageUp, PageDown, etc.) with correct capitalization.","Use single characters for character keys: 'Ctrl+a', not 'Ctrl+a!' typos.","Check token.Keywords / keys.go for the exact supported key set."],"exampleFix":"// before (.tape)\nCtrl+abc\n// after (.tape)\nCtrl+c","handlingStrategy":"validation","validationCode":"func validCtrlArg(a string) bool { if len(a) == 1 { return true }; _, ok := token.Keywords[a]; return ok }","typeGuard":"func isKnownKey(s string) bool { k, ok := token.Keywords[s]; return ok && k != token.ILLEGAL }","tryCatchPattern":null,"preventionTips":["Use vhs's exact key names with correct capitalization (Enter, Space, Tab, Down...)","Single characters for character keys; nothing else in Ctrl chains","Check keys.go / token package for the supported key set"],"tags":["parser","ctrl-command","invalid-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"}