hasura/graphql-engine · error · errors.Error
marshal file: %w
Error message
marshal file: %w
What it means
rawGlobalConfig.write serializes the in-memory global config with json.MarshalIndent before saving; this error wraps a marshaling failure. Because the struct holds plain JSON-compatible values, it essentially only fires when a field contains data JSON cannot represent (NaN/Inf floats, cycles, or unsupported channel/func types after struct changes).
Source
Thrown at cli/global_config.go:100
if c.ShowUpdateNotification == nil {
trueVal := true
c.ShowUpdateNotification = &trueVal
c.shoudlWrite = true
}
if c.CLIEnvironment == "" {
c.CLIEnvironment = DefaultEnvironment
}
return nil
}
func (c *rawGlobalConfig) write(filename string) error {
var op errors.Op = "cli.rawGlobalConfig.write"
b, err := json.MarshalIndent(c, "", " ")
if err != nil {
return errors.E(op, fmt.Errorf("marshal file: %w", err))
}
err = os.WriteFile(filename, b, 0o644)
if err != nil {
return errors.E(op, fmt.Errorf("write file: %w", err))
}
return nil
}
// setupGlobConfig ensures that global config directory and file exists and
// reads it into the GlobalConfig object.
func (ec *ExecutionContext) setupGlobalConfig() error {
var op errors.Op = "cli.ExecutionContext.setupGlobalConfig"
// check if the directory name is set, else default
if len(ec.GlobalConfigDir) == 0 {
ec.Logger.Debug("global config directory is not pre-set, defaulting")
View on GitHub (pinned to 724551b9ae)
Solutions
- Inspect and sanitize config values (replace NaN/Inf with valid numbers or omit the key) before saving
- Regenerate the global config from defaults (delete it and re-run init/setup)
- Pin/align tool versions between write and read paths if a schema change is suspected
Example fix
// before raw.Timeout = math.NaN() // json: unsupported value: NaN // after raw.Timeout = 30 * time.Second
Defensive patterns
Strategy: try-catch
Validate before calling
if _, err := json.MarshalIndent(rawCfg, "", " "); err != nil {
log.Fatalf("global config contains unserializable values: %v", err)
} Type guard
func isMarshalable(v any) bool {
_, err := json.Marshal(v)
return err == nil
} Try / catch
if err := setupGlobalConfig(); err != nil {
var typeErr *json.UnsupportedTypeError
if stderrors.As(err, &typeErr) {
// a struct field holds an unmarshalable value; sanitize or drop it before retrying
}
} Prevention
- Sanitize float fields (reject NaN/Inf) before saving
- Keep tool versions consistent between read and write paths
- Regenerate from defaults when the config becomes unmarshalable
When it happens
Trigger: setupGlobalConfig persisting a rawGlobalConfig containing a NaN or +Inf float (e.g. parsed from an exotic config source) or a struct layout with unmarshalable fields introduced by a version change.
Common situations: Version upgrade adding a field the old writer cannot marshal; programmatic manipulation of the config struct injecting NaN; extremely rare in normal CLI usage.
Related errors
- parse file %w
- read file: %w
- write file: %w
- cannot get home directory: %w
- cannot create global config directory: %w
AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28).
Data as JSON: /api/errors/0d6b6ca744a208e5.
Report an issue: GitHub.