antlr/antlr4 · error
output directory `%s` is not a directory
Error message
output directory `%s` is not a directory
What it means
Returned as an error by goRunStats.Report() in the Go runtime when the dir argument exists but is not a directory (isDirectory reports false). Report writes markdown statistics files into that directory, so a regular file at the path is unusable.
Source
Thrown at runtime/Go/antlr/v4/statistics.go:139
sort.Slice(s.jStats, func(i, j int) bool {
return s.jStats[i].Gets+s.jStats[i].Puts > s.jStats[j].Gets+s.jStats[j].Puts
})
for i := 0; i < len(s.jStats) && i < s.topN; i++ {
s.topNByUsed = append(s.topNByUsed, s.jStats[i])
}
}
// Report dumps a markdown formatted report of all the statistics collected during a run to the given dir output
// path, which should represent a directory. Generated files will be prefixed with the given prefix and will be
// given a type name such as `anomalies` and a time stamp such as `2021-09-01T12:34:56` and a .md suffix.
func (s *goRunStats) Report(dir string, prefix string) error {
isDir, err := isDirectory(dir)
switch {
case err != nil:
return err
case !isDir:
return fmt.Errorf("output directory `%s` is not a directory", dir)
}
s.reportCollections(dir, prefix)
// Clean out any old data in case the user forgets
//
s.Reset()
return nil
}
func (s *goRunStats) Reset() {
s.jStats = nil
s.topNByUsed = nil
s.topNByMax = nil
}
func (s *goRunStats) reportCollections(dir, prefix string) {
cname := filepath.Join(dir, ".asciidoctor")
// If the file doesn't exist, create it, or append to the fileView on GitHub (pinned to 7d5770395b)
Solutions
- Point Report() at an existing directory
- Create the directory first with os.MkdirAll(dir, 0755) before calling Report
- Check the returned error and log it; note Report also resets stats, so only re-run after fixing the path
Example fix
// before
err := stats.Report("/tmp/report.md", "run")
// after
err := os.MkdirAll("/tmp/reports", 0o755)
if err != nil { return err }
err = stats.Report("/tmp/reports", "run") Defensive patterns
Strategy: validation
Validate before calling
info, err := os.Stat(dir)
if err != nil || !info.IsDir() {
if err := os.MkdirAll(dir, 0o755); err != nil {
return err
}
}
err = stats.Report(dir, prefix) Type guard
func isDir(path string) bool {
info, err := os.Stat(path)
return err == nil && info.IsDir()
} Try / catch
if err := stats.Report(dir, prefix); err != nil {
if strings.Contains(err.Error(), "is not a directory") {
// fix path and mkdir, then retry once
}
} Prevention
- Create the output directory with MkdirAll before calling Report
- Always check Report's returned error; Report also resets stats on success
When it happens
Trigger: Calling stats.Report('/some/path/file.txt', 'prefix') or any path occupied by a symlink/file, or when isDirectory fails on a broken path.
Common situations: Configured statistics output path pointing at a file, a missing parent directory combined with a stale file, or running with a path from a different environment.
Related errors
- LexerNoViableAltException + symbol
- FileStream is only available when running in Node!
- replace: range invalid: ${from}..${to}(size=${this.tokens.si
- replace op boundaries of ${rop} overlap with previous ${prev
- insert op ${iop} within boundaries of previous ${rop}
AI-assisted analysis of antlr/antlr4@7d5770395b (2026-08-14).
Data as JSON: /api/errors/0bd7edf5630b346c.
Report an issue: GitHub.