hasura/graphql-engine · error · errors.Error

read file: %w

Error message

read file: %w

What it means

rawGlobalConfig.read loads the global JSON config file with os.ReadFile; this error wraps any read failure such as not-exist or permission denied. It occurs during setupGlobalConfig, i.e. early in CLI startup when the per-user global configuration is loaded.

Source

Thrown at cli/global_config.go:55

	// CLIEnvironment defines the environment the CLI is running
	CLIEnvironment Environment `json:"cli_environment"`
}

type rawGlobalConfig struct {
	UUID                   *string     `json:"uuid"`
	EnableTelemetry        *bool       `json:"enable_telemetry"`
	ShowUpdateNotification *bool       `json:"show_update_notification"`
	CLIEnvironment         Environment `json:"cli_environment"`

	shoudlWrite bool
}

func (c *rawGlobalConfig) read(filename string) error {
	var op errors.Op = "cli.rawGlobalConfig.read"

	b, err := os.ReadFile(filename)
	if err != nil {
		return errors.E(op, fmt.Errorf("read file: %w", err))
	}

	err = json.Unmarshal(b, c)
	if err != nil {
		return errors.E(op, fmt.Errorf("parse file %w", err))
	}

	return nil
}

func (c *rawGlobalConfig) validateKeys() error {
	// check prescence of uuid, create if doesn't exist
	if c.UUID == nil {
		uid := uuid.NewString()
		c.UUID = &uid
		c.shoudlWrite = true
	}

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Run the tool's init/setup once so the global config is created, or create it manually with {}
  2. Verify HOME and XDG_CONFIG_HOME are set correctly in the environment (cron, systemd, containers)
  3. Fix ownership/permissions: ls -l on the config path, chown back to your user

Example fix

# before
# ~/.config/tool/global.json missing
mycli run
# after
mkdir -p ~/.config/tool && echo '{}' > ~/.config/tool/global.json && mycli run
Defensive patterns

Strategy: validation

Validate before calling

path := configPath() // e.g. ~/.config/tool/global.json
if _, err := os.Stat(path); err != nil {
    if stderrors.Is(err, fs.ErrNotExist) {
        _ = os.MkdirAll(filepath.Dir(path), 0o755)
        _ = os.WriteFile(path, []byte("{}"), 0o644)
    } else {
        log.Fatalf("cannot read global config: %v", err)
    }
}

Try / catch

if err := setupGlobalConfig(); err != nil {
    var pathErr *os.PathError
    if stderrors.As(err, &pathErr) && stderrors.Is(pathErr, fs.ErrNotExist) {
        // first run: create defaults and retry
    }
}

Prevention

When it happens

Trigger: setupGlobalConfig pointing at a global config path (e.g. ~/.config/tool/global.json) that does not exist, is unreadable due to permissions, or sits on an unavailable mount.

Common situations: First run of the tool before any global config was written; HOME/XDG_CONFIG_HOME unset or wrong in CI or cron; config file owned by root after sudo runs; broken symlinks.

Related errors


AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28). Data as JSON: /api/errors/623afec1a1e12bc7. Report an issue: GitHub.