slimtoolkit/slim · error

sensor: artifact - getNuxtConfig - error reading file =>

Error message

sensor: artifact - getNuxtConfig - error reading file => %s

What it means

After the stat check passes, getNuxtConfig reads the nuxt.config file with os.ReadFile. If the read fails (permissions, I/O error, file removed between stat and read), it logs the details at debug level and returns this error naming the path.

Solutions

  1. Check the debug log for the exact ReadFile error (EACCES vs ENOENT vs EISDIR).
  2. Grant read permission on the config file/directory to the sensor's user.
  3. Confirm the path is a regular file, not a directory or dangling symlink.
  4. Retry the scan if the file was transiently removed during a build.

Example fix

// before
dat, err := os.ReadFile(path)
// after
dat, err := os.ReadFile(path)
if err != nil && errors.Is(err, os.ErrPermission) {
    return nil, fmt.Errorf("sensor: artifact - getNuxtConfig - permission denied reading %s: %w", path, err)
}
Defensive patterns

Strategy: validation

Validate before calling

fi, err := os.Stat(configPath)
if err != nil {
    return fmt.Errorf("config inaccessible: %w", err)
}
if !fi.Mode().IsRegular() {
    return fmt.Errorf("%s is not a regular file", configPath)
}
f, err := os.Open(configPath)
if err != nil {
    return fmt.Errorf("no read permission on %s: %w", configPath, err)
}
f.Close()

Try / catch

nuxt, err := getNuxtConfig(configPath)
if err != nil {
    if strings.Contains(err.Error(), "error reading file") {
        return fmt.Errorf("fix permissions on %s for the sensor user: %w", configPath, err)
    }
    return err
}

Prevention

When it happens

Trigger: os.ReadFile on an existing nuxt.config path fails — file is a directory/symlink target missing, permission denied for the sensor's user, or the file was deleted between the Stat call and the ReadFile call.

Common situations: Sensor running as a different user than the app files' owner (no read permission); encrypted or bind-mounted volumes with restrictive modes; race where the build pipeline removes the config during scanning.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of slimtoolkit/slim@81940d17fa (2026-08-31). Data as JSON: /api/errors/958ea702c6f72256. Report an issue: GitHub.

Appendix: source

Thrown at pkg/app/sensor/artifact/artifact.go:3022

	return nil
}

type nuxtDirs struct {
	Build string
	Dist  string
}

func getNuxtConfig(path string) (*nuxtDirs, error) {
	if _, err := os.Stat(path); err != nil && os.IsNotExist(err) {
		log.Debugf("sensor: monitor - getNuxtConfig - err stat => %s - %s", path, err.Error())
		return nil, fmt.Errorf("sensor: artifact - getNuxtConfig - error getting file => %s", path)
	}

	dat, err := os.ReadFile(path)
	if err != nil {
		log.Debugf("sensor: monitor - getNuxtConfig - err reading file => %s - %s", path, err.Error())
		return nil, fmt.Errorf("sensor: artifact - getNuxtConfig - error reading file => %s", path)
	}

	log.Tracef("sensor: monitor - getNuxtConfig(%s) - %s", path, string(dat))

	nuxt := nuxtDirs{
		Build: nuxtDefaultBuildDir,
		Dist:  fmt.Sprintf("%s/%s", nuxtDefaultBuildDir, nuxtDefaultDistDir),
	}

	/*
		todo: need more test apps to verify this part of the code
		vm := otto.New()
		vm.Run(dat)

		if value, err := vm.Get(nuxtBuildDirKey); err == nil {
			if v, err := value.ToString(); err == nil {
				nuxt.Build = v
			} else {

View on GitHub (pinned to 81940d17fa)