charmbracelet/glow · error

unable to open file: %w

Error message

unable to open file: %w

What it means

This is the last-resort branch of sourceFromArg: the argument was not a URL and not a directory, so glow tries os.Open(arg) as a file. Failure means the file could not be opened - it is missing, permission denied, or a dangling symlink - with the raw OS error wrapped with %w. Unlike the directory branch, no existence check happens before the open.

Source

Thrown at main.go:143

					src = &source{r, u}

					// abort filepath.Walk
					return errors.New("source found")
				}
			}
			return nil
		})

		if src != nil {
			return src, nil
		}

		return nil, errors.New("missing markdown source")
	}

	r, err := os.Open(arg)
	if err != nil {
		return nil, fmt.Errorf("unable to open file: %w", err)
	}
	u, err := filepath.Abs(arg)
	if err != nil {
		return nil, fmt.Errorf("unable to get absolute path: %w", err)
	}
	return &source{r, u}, nil
}

// validateStyle checks if the style is a default style, if not, checks that
// the custom style exists.
func validateStyle(style string) error {
	if style != "auto" && styles.DefaultStyles[style] == nil {
		style = utils.ExpandPath(style)
		if _, err := os.Stat(style); errors.Is(err, fs.ErrNotExist) {
			return fmt.Errorf("specified style does not exist: %s", style)
		} else if err != nil {
			return fmt.Errorf("unable to stat file: %w", err)
		}

View on GitHub (pinned to e3970c813d)

Solutions

  1. Check existence and readability: ls -l <path>
  2. Fix permissions (chmod +r) or run with appropriate privileges
  3. Verify the path spelling and the current working directory for relative paths
Defensive patterns

Strategy: validation

Validate before calling

func readableFile(path string) error {
	fi, err := os.Stat(path)
	if err != nil { return err }
	if fi.IsDir() { return fmt.Errorf("%s is a directory", path) }
	if fi.Mode().Perm()&0o400 == 0 { return fmt.Errorf("%s is not readable", path) }
	return nil
}

Type guard

func isNotExist(err error) bool { return errors.Is(err, fs.ErrNotExist) }

Prevention

When it happens

Trigger: Path does not exist (ENOENT); file exists but is not readable by the current user (EACCES); dangling symlink; special file that cannot be opened in the current context.

Common situations: Typos in filenames, running as a different user than the file owner, files with 0600 permissions owned elsewhere, scripts invoking glow with unquoted paths that get split by the shell.

Related errors


AI-assisted analysis of charmbracelet/glow@e3970c813d (2026-08-15). Data as JSON: /api/errors/f2ff9c98aa47b434. Report an issue: GitHub.