grafana/k6 · warning
removing downloads path: %w
Error message
removing downloads path: %w
What it means
During BrowserContext.cleanup (browser_context.go:112), k6 runs os.RemoveAll on the downloads directory it created for the context. If the removal fails — permission loss, files held open, failing mount — the error is wrapped as 'removing downloads path: %w'. The context itself is still considered closed; the practical impact is a leaked temp directory.
Source
Thrown at internal/js/modules/k6/browser/common/browser_context.go:112
func (b *BrowserContext) setDownloadsPath(path string) error {
path = strings.TrimSpace(path)
if path != "" {
b.DownloadsPath = path
return nil
}
dir, err := os.MkdirTemp(os.TempDir(), artifactsDirectory+"*") //nolint:forbidigo
if err != nil {
return fmt.Errorf("creating temporary directory for downloads: %w", err)
}
b.DownloadsPath = dir
return nil
}
// cleanup cleans up the resources associated with the browser context.
func (b *BrowserContext) cleanup() error {
if err := os.RemoveAll(b.DownloadsPath); err != nil { //nolint:forbidigo
return fmt.Errorf("removing downloads path: %w", err)
}
b.DownloadsPath = ""
return nil
}
// NewBrowserContext creates a new browser context.
func NewBrowserContext(
ctx context.Context, browser *Browser, id cdp.BrowserContextID, opts *BrowserContextOptions, logger *log.Logger,
) (*BrowserContext, error) {
// set the default options if none provided.
if opts == nil {
opts = DefaultBrowserContextOptions()
}
// Always use the [Browser]'s user agent if it's not set by the user.
// Setting this forces [FrameSession] to set Chromium's user agent.
if strings.TrimSpace(opts.UserAgent) == "" {
opts.UserAgent = browser.UserAgent()View on GitHub (pinned to 93accf6570)
Solutions
- Check the wrapped syscall error (EACCES/EBUSY) and fix permissions or close file handles before context close
- Clean leftover artifacts-* dirs under /tmp between runs
- Use an explicit downloadsPath on a volume you manage so cleanup is deterministic
Defensive patterns
Strategy: try-catch
Validate before calling
// close file handles and stop writers before ending the context // use an explicit downloadsPath you control to make cleanup predictable
Try / catch
try {
await ctx.close()
} catch (e) {
if (/removing downloads path/.test(String(e))) {
// context is closed; schedule manual cleanup of the leaked artifacts-* dir
} else throw e
} Prevention
- Close downloaded files before closing the context
- Use an explicit downloadsPath so cleanup does not depend on /tmp
- Sweep leftover artifacts-* dirs between CI runs
When it happens
Trigger: Files in the download directory still held/locked by another process; directory on NFS/FUSE returning errors; the k6 process losing permission (uid change, SELinux); path already altered by concurrent cleanup.
Common situations: Downloaded files still open when the context closes; exotic mounts in CI; leftover /tmp/artifacts-* dirs accumulating after repeated failures.
Related errors
- creating temporary directory for downloads: %w
- setting downloads path: %w
- open() failed; reason: unable to access the file system
- serialising archive: %w
- couldn't load the configuration from %q: %w
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/becdedfaf2e3bfb2.
Report an issue: GitHub.