crowdsecurity/crowdsec · error

while reading %s: %w

Error message

while reading %s: %w

What it means

After globbing parser.assert files, GetParsersCoverage opens each one with os.Open. If opening a specific assert file fails, the function stops and returns 'while reading <path>: <err>'. The wrapped os error (e.g. permission denied) identifies the actual cause.

Source

Thrown at pkg/hubtest/coverage.go:116

	for i, name := range pkeys {
		coverage[i] = Coverage{
			Name:       name,
			TestsCount: 0,
			PresentIn:  make(map[string]bool),
		}
	}

	// parser the expressions a-la-oneagain
	passerts, err := filepath.Glob(filepath.Join(hubDir, ".tests", "*", "parser.assert"))
	if err != nil {
		return nil, fmt.Errorf("while find parser asserts: %w", err)
	}

	for _, assert := range passerts {
		file, err := os.Open(assert)
		if err != nil {
			return nil, fmt.Errorf("while reading %s: %w", assert, err)
		}

		scanner := bufio.NewScanner(file)
		for scanner.Scan() {
			line := scanner.Text()
			log.Debugf("assert line : %s", line)

			match := parserResultRE.FindStringSubmatch(line)
			if len(match) == 0 {
				log.Debugf("%s doesn't match", line)
				continue
			}

			sidx := parserResultRE.SubexpIndex("parser")
			capturedParser := match[sidx]

			for idx, pcover := range coverage {
				if pcover.Name == capturedParser {

View on GitHub (pinned to 909b515798)

Solutions

  1. Check permissions on the reported parser.assert path (ls -l) and chmod/chown so the running user can read it
  2. Verify the path is a regular file, not a directory; remove/recreate it if wrong
  3. Re-run hub update / re-checkout to replace a truncated or missing assert file
  4. Run hubtest with the same user that owns the hub directory

Example fix

// before
-rw------- parser.assert  (owned by root, hubtest runs as ci)
// after
chmod 644 parser.assert && chown ci:ci parser.assert
Defensive patterns

Strategy: try-catch

Validate before calling

info, err := os.Stat(assertPath)
if err != nil || info.IsDir() { return fmt.Errorf("unreadable assert %s", assertPath) }
if f, err := os.Open(assertPath); err == nil { f.Close() }

Try / catch

cov, err := hubtest.GetParsersCoverage(hubDir, ...)
if err != nil {
    var pe *fs.PathError
    if errors.As(err, &pe) { log.Fatalf("cannot read %s: %v — check permissions", pe.Path, pe.Err) }
}

Prevention

When it happens

Trigger: os.Open fails on a parser.assert path: the file was deleted between glob and open, the file is a directory named parser.assert, or the process lacks read permission on it.

Common situations: Tests directory mounted read-only or owned by another user (CI running as non-root); a stale glob result after the hub cache was concurrently updated; someone created a directory named parser.assert.

Understand the failure class

Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.

Related errors


AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06). Data as JSON: /api/errors/ec420fa62b0a0b59. Report an issue: GitHub.