hasura/graphql-engine · error · errors.Error

writing global config file failed: %w

Error message

writing global config file failed: %w

What it means

The existing config file was read and validated, but a migration/normalization set gc.shoudlWrite = true and the subsequent rewrite of the file failed with an I/O error. Same failure class as 210/214 (unwritable path, read-only FS, locked file) but on the rewrite-after-read path.

Source

Thrown at cli/global_config.go:194

		// initialize the config object
		gc := rawGlobalConfig{}

		err := gc.read(ec.GlobalConfigFile)
		if err != nil {
			return errors.E(op, fmt.Errorf("reading global config file failed: %w", err))
		}

		// validate keys
		err = gc.validateKeys()
		if err != nil {
			return errors.E(op, fmt.Errorf("validating global config file failed: %w", err))
		}

		// write the file if there are any changes
		if gc.shoudlWrite {
			err := gc.write(ec.GlobalConfigFile)
			if err != nil {
				return errors.E(op, fmt.Errorf("writing global config file failed: %w", err))
			}

			ec.Logger.Debugf(
				"global config file written at '%s' with content '%+#v'",
				ec.GlobalConfigFile,
				gc,
			)
		}
	}

	err = ec.readGlobalConfig()
	if err != nil {
		return errors.E(op, err)
	}

	return nil
}

View on GitHub (pinned to 724551b9ae)

Solutions

  1. chmod 644 + chown to the running user so the file is writable, or chmod 444->644
  2. Make the config file byte-for-byte canonical (correct keys/format) so no rewrite is triggered
  3. Mount the config volume read-write if it is currently read-only
  4. Pre-apply migrations with a matching CLI version that can write the file

Example fix

# before
-rw-r--r-- 1 root root ~/.mycli/config.yaml
# after
$ sudo chown $(id -u):$(id -g) ~/.mycli/config.yaml
Defensive patterns

Strategy: validation

Validate before calling

if info, err := os.Stat(ec.GlobalConfigFile); err == nil {
    if info.Mode().Perm()&0o200 == 0 {
        return fmt.Errorf("config file %s is not writable; migrations will fail", ec.GlobalConfigFile)
    }
}

Type guard

func fileIsWritable(p string) bool {
    f, err := os.OpenFile(p, os.O_WRONLY, 0)
    if err != nil {
        return false
    }
    _ = f.Close()
    return true
}

Try / catch

if err := ec.Prepare(ctx); err != nil {
    if strings.Contains(err.Error(), "writing global config file failed") {
        _ = os.Chmod(ec.GlobalConfigFile, 0o644)
        return ec.Prepare(ctx)
    }
    return err
}

Prevention

When it happens

Trigger: Config file is readable but not writable (0644 root-owned while running as a normal user) exactly when the CLI needs to persist added/normalized keys, or the file is locked by another process on Windows.

Common situations: Configs deployed via configuration management as root-owned files, then executed by unprivileged users; read-only mounted config volumes; editors holding locks.

Related errors


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