projectdiscovery/katana · error

could not create graph file

Error message

could not create graph file

What it means

CrawlGraph.DrawGraph renders the crawl graph as a DOT file for debugging. This error wraps a failure of os.Create(file), meaning the output file could not be created — typically a bad path, missing directory, or permission problem. The graph is never rendered; the call fails immediately.

Source

Thrown at pkg/engine/headless/graph/graph.go:136

	actionsSlice := make([]*types.Action, 0, len(shortestPath))
	for _, path := range shortestPath {
		pageVertex, err := g.graph.Vertex(path)
		if err != nil {
			return nil, errors.Wrap(err, "could not get vertex")
		}

		if pageVertex.URL == "about:blank" || pageVertex.NavigationAction == nil {
			continue
		}
		actionsSlice = append(actionsSlice, pageVertex.NavigationAction)
	}
	return actionsSlice, nil
}

func (g *CrawlGraph) DrawGraph(file string) error {
	f, err := os.Create(file)
	if err != nil {
		return errors.Wrap(err, "could not create graph file")
	}
	defer func() { _ = f.Close() }()

	return draw.DOT(g.graph, f)
}

View on GitHub (pinned to e3e742739c)

Solutions

  1. Create the parent directory first (os.MkdirAll(filepath.Dir(file), 0o755)) before calling DrawGraph.
  2. Verify the process has write permission on the target path (ls -ld on the directory).
  3. Use a writable location such as os.TempDir() or an explicitly configured debug output directory.
  4. Check the file path for typos, empty strings, or invalid characters.

Example fix

// before
if err := crawlGraph.DrawGraph("debug/graph.dot"); err != nil { ... }
// after
_ = os.MkdirAll("debug", 0o755)
if err := crawlGraph.DrawGraph("debug/graph.dot"); err != nil { ... }
Defensive patterns

Strategy: validation

Validate before calling

dir := filepath.Dir(graphFile)
if err := os.MkdirAll(dir, 0o755); err != nil {
    return fmt.Errorf("cannot create graph output dir %s: %w", dir, err)
}
if err := os.WriteFile(graphFile, nil, 0o644); err != nil {
    return fmt.Errorf("graph output path not writable: %w", err)
}

Try / catch

// Go: wrap DrawGraph with directory creation
if err := os.MkdirAll(filepath.Dir(file), 0o755); err != nil { return err }
if err := crawlGraph.DrawGraph(file); err != nil {
    return fmt.Errorf("draw graph to %s: %w", file, err)
}

Prevention

When it happens

Trigger: Calling DrawGraph with a path whose parent directory does not exist, with an invalid filename (e.g. empty string, path separators in a filename component), or to a location the process lacks write permission for (e.g. read-only container filesystem).

Common situations: Enabling graph debugging in a container where /tmp or the working directory is read-only; typo in the debug output path; running as a non-root user writing to a root-owned directory.

Related errors


AI-assisted analysis of projectdiscovery/katana@e3e742739c (2026-09-03). Data as JSON: /api/errors/79919ed8b655807d. Report an issue: GitHub.