charmbracelet/vhs · error · parser.Error
Expected path after Source
Error message
Expected path after Source
What it means
parseSource requires a STRING path token after the Source directive. If absent, it records "Expected path after Source" and returns immediately. Source includes another .tape file, so a path argument is mandatory.
Source
Thrown at parser/parser.go:676
if p.peek.Type != token.STRING {
p.errors = append(p.errors, NewError(p.peek, p.cur.Literal+" expects string"))
}
cmd.Args = p.peek.Literal
p.nextToken()
return cmd
}
// parseSource parses source command.
// Source command takes a tape path to include in current tape.
//
// Source <path>
func (p *Parser) parseSource() []Command {
cmd := Command{Type: token.SOURCE}
if p.peek.Type != token.STRING {
p.errors = append(p.errors, NewError(p.cur, "Expected path after Source"))
p.nextToken()
return []Command{cmd}
}
srcPath := p.peek.Literal
// Check if path has .tape extension
ext := filepath.Ext(srcPath)
if ext != ".tape" {
p.errors = append(p.errors, NewError(p.peek, "Expected file with .tape extension"))
p.nextToken()
return []Command{cmd}
}
// Check if tape exist
if _, err := os.Stat(srcPath); os.IsNotExist(err) { //nolint:gosec
notFoundErr := fmt.Sprintf("File %s not found", srcPath)
p.errors = append(p.errors, NewError(p.peek, notFoundErr))View on GitHub (pinned to c073383b5d)
Solutions
- Add a quoted path: `Source "other.tape"`
- Remove the Source line if it is unused
- Confirm the path token is double-quoted so the lexer emits a STRING
Example fix
// before Source other.tape // after Source "other.tape"
Defensive patterns
Strategy: validation
Validate before calling
if strings.TrimSpace(line) == "Source" {
return fmt.Errorf("Source requires a quoted .tape path")
}
if strings.HasPrefix(line, "Source ") && !strings.Contains(line, `"`) {
return fmt.Errorf("Source path must be double-quoted")
} Type guard
func sourceHasPath(t token.Token) bool { return t.Type == token.STRING && t.Literal != "" } Try / catch
if err := parse(tape); err != nil && strings.Contains(err.Error(), "Expected path after Source") {
return fmt.Errorf("bad Source directive in %s: %w", tape, err)
} Prevention
- Always write Source "file.tape" with quotes
- Keep one directive per line
- Add a pre-run syntax check of all tape files
When it happens
Trigger: A .tape file containing bare `Source` with no argument, or an unquoted token (e.g. `Source other.tape` without quotes) so the path token is not of type STRING when parseSource runs.
Common situations: Copy-pasting `Source` examples without quotes; forgetting the argument when commenting out the path; concatenating lines so the path lands on the wrong line.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Nested Source detected
- ${srcPath} has ${count} errors
- Expected path after Screenshot
- Invalid command: ${literal}
- Wait+ expects Line or Screen
AI-assisted analysis of charmbracelet/vhs@c073383b5d (2026-09-02).
Data as JSON: /api/errors/3496d2a1f206ce8c.
Report an issue: GitHub.