{"record":{"id":"2a720303c7d3e7b3","repo":"charmbracelet/vhs","slug":"wait-expects-line-or-screen","errorCode":null,"errorMessage":"Wait+ expects Line or Screen","messagePattern":"Wait\\+ expects Line or Screen","errorType":"validation","errorClass":"parser.Error","httpStatus":null,"severity":"error","filePath":"parser/parser.go","lineNumber":200,"sourceCode":"\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}\n\n\tcmd.Options = p.parseSpeed()\n\tif cmd.Options != \"\" {\n\t\tdur, _ := time.ParseDuration(cmd.Options)\n\t\tif dur <= 0 {\n\t\t\tp.errors = append(p.errors, NewError(p.peek, \"Wait expects positive duration\"))\n\t\t\treturn cmd\n\t\t}\n\t}\n\n\tif p.peek.Type != token.REGEX {","sourceCodeStart":182,"sourceCodeEnd":218,"githubUrl":"https://github.com/charmbracelet/vhs/blob/c073383b5de0b1f57bf514113029c306bc986539/parser/parser.go#L182-L218","documentation":"vhs's Wait command blocks until a pattern appears on the screen; Wait+ optionally takes a match target. parseWait accepts 'Wait+ Line' (match on a single line) or 'Wait+ Screen' (match the whole screen); any other token after the '+' raises this error. It exists because Wait+ is strict: the only valid plus-arguments are the literal strings 'Line' and 'Screen'.","triggerScenarios":"Writing 'Wait+ Line' / 'Wait+ Screen' with anything other than exactly the token STRING 'Line' or 'Screen' after '+', e.g. 'Wait+ line' (lowercase), 'Wait+ Text', 'Wait+ 5', or 'Wait+ Pattern'.","commonSituations":"Case-sensitivity mistakes ('line' vs 'Line'); guessing the Wait+ option name from memory; copying syntax from other wait libraries that accept arbitrary targets.","solutions":["Use exactly 'Wait+ Line' or 'Wait+ Screen' (capitalized, no quotes needed unless you prefer quoting the string).","If you want to wait for specific text, use Wait with a regex after the type: 'Wait+ Screen<regex>...' as supported by vhs (e.g. 'Wait+ Screen /pattern/').","Drop the '+' and use plain 'Wait' which defaults to Line matching."],"exampleFix":"// before (.tape)\nWait+ line\n// after (.tape)\nWait+ Line","handlingStrategy":"validation","validationCode":"func validWaitPlus(arg string) bool { return arg == \"Line\" || arg == \"Screen\" }","typeGuard":"func isWaitTarget(s string) bool { switch s { case \"Line\", \"Screen\": return true }; return false }","tryCatchPattern":null,"preventionTips":["Remember Wait+ targets are exact, capitalized literals: Line or Screen","Use plain 'Wait' (defaults to Line) unless you specifically need Screen matching","Add a regex after the target to match specific text"],"tags":["parser","wait-command","invalid-argument"],"backgroundTag":"invalid-argument-value","analyzedSha":"c073383b5de0b1f57bf514113029c306bc986539","analyzedAt":"2026-09-02T01:53:05.682Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}