charmbracelet/vhs · error · parser.Error
Wait+ expects Line or Screen
Error message
Wait+ expects Line or Screen
What it means
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'.
Source
Thrown at parser/parser.go:200
case token.COPY:
return []Command{p.parseCopy()}
case token.PASTE:
return []Command{p.parsePaste()}
case token.ENV:
return []Command{p.parseEnv()}
default:
p.errors = append(p.errors, NewError(p.cur, "Invalid command: "+p.cur.Literal))
return []Command{{Type: token.ILLEGAL}}
}
}
func (p *Parser) parseWait() Command {
cmd := Command{Type: token.WAIT}
if p.peek.Type == token.PLUS {
p.nextToken()
if p.peek.Type != token.STRING || (p.peek.Literal != "Line" && p.peek.Literal != "Screen") {
p.errors = append(p.errors, NewError(p.peek, "Wait+ expects Line or Screen"))
return cmd
}
cmd.Args = p.peek.Literal
p.nextToken()
} else {
cmd.Args = "Line"
}
cmd.Options = p.parseSpeed()
if cmd.Options != "" {
dur, _ := time.ParseDuration(cmd.Options)
if dur <= 0 {
p.errors = append(p.errors, NewError(p.peek, "Wait expects positive duration"))
return cmd
}
}
if p.peek.Type != token.REGEX {View on GitHub (pinned to c073383b5d)
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.
Example fix
// before (.tape) Wait+ line // after (.tape) Wait+ Line
Defensive patterns
Strategy: validation
Validate before calling
func validWaitPlus(arg string) bool { return arg == "Line" || arg == "Screen" } Type guard
func isWaitTarget(s string) bool { switch s { case "Line", "Screen": return true }; return false } Prevention
- 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
When it happens
Trigger: 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'.
Common situations: Case-sensitivity mistakes ('line' vs 'Line'); guessing the Wait+ option name from memory; copying syntax from other wait libraries that accept arbitrary targets.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Wait expects positive duration
- Invalid regular expression '${literal}': ${err}
- Not a valid modifier
- Invalid control argument: ${literal}
- Invalid command: ${literal}
AI-assisted analysis of charmbracelet/vhs@c073383b5d (2026-09-02).
Data as JSON: /api/errors/2a720303c7d3e7b3.
Report an issue: GitHub.