charmbracelet/vhs · error · parser.Error
Wait expects positive duration
Error message
Wait expects positive duration
What it means
When a Wait command is followed by '@<duration>' (parsed via parseSpeed into Options), vhs validates the duration with time.ParseDuration and requires it to be strictly positive. This error fires when the Wait timeout is zero or negative, e.g. 'Wait@0s' or 'Wait@-1s'.
Source
Thrown at parser/parser.go:213
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 {
// fallback to default
return cmd
}
p.nextToken()
if _, err := regexp.Compile(p.cur.Literal); err != nil {
p.errors = append(p.errors, NewError(p.cur, fmt.Sprintf("Invalid regular expression '%s': %v", p.cur.Literal, err)))
return cmd
}
cmd.Args += " " + p.cur.Literal
return cmd
}View on GitHub (pinned to c073383b5d)
Solutions
- Use a positive duration, e.g. 'Wait@5s' or 'Wait@500ms'.
- Remove the '@duration' clause entirely to use the default timeout.
- Check unit suffixes are valid Go durations (ms, s, m, h).
Example fix
// before (.tape) Wait@0s Screen // after (.tape) Wait@5s Screen
Defensive patterns
Strategy: validation
Validate before calling
func isPositiveDuration(d string) bool { dur, err := time.ParseDuration(strings.TrimPrefix(d, "@")); return err == nil && dur > 0 } Prevention
- Always pair Wait@ with a positive Go-style duration (500ms, 5s, 1m)
- Never use Wait@0 — omit the @ clause for defaults
- Test durations locally before committing tapes
When it happens
Trigger: Any 'Wait@<duration>' where time.ParseDuration returns a value <= 0: 'Wait@0', 'Wait@0s', 'Wait@-500ms', or an unparseable value that yields dur <= 0 (parse error is swallowed by the '_').
Common situations: Setting a zero timeout to mean 'no timeout' (vhs does not accept 0 here); accidentally using a negative duration; typos in unit suffix causing the duration to parse to 0.
Related errors
- Wait+ expects Line or Screen
- Invalid regular expression '${literal}': ${err}
- Expected time after ${literal}
- Invalid command: ${literal}
- Modifiers must come before other characters
AI-assisted analysis of charmbracelet/vhs@c073383b5d (2026-09-02).
Data as JSON: /api/errors/f82a80f438db58b8.
Report an issue: GitHub.