hasura/graphql-engine · error · errors.Error
write global config file: %w
Error message
write global config file: %w
What it means
During first-run initialization, gc.write(ec.GlobalConfigFile) failed after the empty config object was successfully created and validated. It is a plain disk I/O failure writing the marshaled YAML/JSON — the same class as error 210, but occurring on the create-new-file path rather than the rewrite path.
Source
Thrown at cli/global_config.go:161
if stderrors.Is(err, fs.ErrNotExist) {
// file does not exist, teat as first run and create it
ec.Logger.Debug(
"global config file does not exist, this could be the first run, creating it...",
)
// create an empty config object
gc := &rawGlobalConfig{}
// populate the keys
err := gc.validateKeys()
if err != nil {
return errors.E(op, fmt.Errorf("setup global config object: %w", err))
}
// write the file
err = gc.write(ec.GlobalConfigFile)
if err != nil {
return errors.E(op, fmt.Errorf("write global config file: %w", err))
}
ec.Logger.Debugf(
"global config file written at '%s' with content '%v'",
ec.GlobalConfigFile,
gc,
)
// also show a notice about telemetry
ec.Logger.Info(TelemetryNotice)
} else if stderrors.Is(err, fs.ErrExist) || err == nil {
// file exists, verify contents
ec.Logger.Debug("global config file exists, verifying contents")
// initialize the config object
gc := rawGlobalConfig{}
err := gc.read(ec.GlobalConfigFile)View on GitHub (pinned to 724551b9ae)
Solutions
- chmod/chown the config directory so the invoking user can create files in it
- Pre-create the config file manually with valid content so initialization skips writing
- Move GlobalConfigDir to a writable path
- On Windows, check AV/EDR is not locking the config path
Example fix
# before $ mycli setup # fails on first run # after $ sudo chown -R $(id -u):$(id -g) ~/.mycli $ mycli setup
Defensive patterns
Strategy: validation
Validate before calling
if _, err := os.Stat(ec.GlobalConfigFile); errors.Is(err, os.ErrNotExist) {
if err := os.WriteFile(ec.GlobalConfigFile, []byte("uuid: \"\"\ncli_environment: \"\"\n"), 0o644); err != nil {
return fmt.Errorf("cannot pre-seed config file: %w", err)
}
} Type guard
func canCreateFileIn(dir string) bool {
f, err := os.CreateTemp(dir, ".probe")
if err != nil {
return false
}
_ = f.Close()
_ = os.Remove(f.Name())
return true
} Try / catch
if err := ec.Prepare(ctx); err != nil {
if strings.Contains(err.Error(), "write global config file") && ec.GlobalConfigFile != "" {
ec.GlobalConfigFile = filepath.Join(os.TempDir(), GlobalConfigFileName)
return ec.Prepare(ctx)
}
return err
} Prevention
- Pre-seed a minimal valid config file during provisioning
- Ensure the invoking user owns the config directory before first run
- Use writable mounts for config in containers
When it happens
Trigger: Fresh install where the config file does not yet exist and the directory exists but is not writable (MkdirAll with os.ModePerm can succeed on a dir that is still not writable for the invoking user, e.g. sticky-bit or umask interactions), or a read-only filesystem.
Common situations: First run in a container, first run as a user without write access to the config dir created by an installer (root-owned ~/.<app>), or antivirus/mandatory locking on Windows blocking file creation.
Related errors
- write file: %w
- cannot create global config directory: %w
- writing global config file failed: %w
- writing metadata to file: %w
- error getting directory details: %w
AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28).
Data as JSON: /api/errors/140105c04af653c0.
Report an issue: GitHub.