hasura/graphql-engine · error

error encoding migration status as json: %w

Error message

error encoding migration status as json: %w

What it means

StatusJSON failed while streaming a json.Encoding of the migration status value into a buffer. This is a stdlib encoding/json failure, which for an in-memory bytes.Buffer-backed encoder is only produced by the value's MarshalJSON method returning an error. The library wraps it with errors.E under the op 'StatusJSON' (or similar) so it carries the operation context.

Source

Thrown at cli/pkg/migrate/status.go:86

	}

	return migrateStatus, nil
}

func (p *projectMigrationsStatus) StatusJSON(
	opts ...ProjectMigrationStatusOption,
) (io.Reader, error) {
	var op errors.Op = "migrate.projectMigrationsStatus.StatusJSON"

	d, err := p.Status(opts...)
	b := new(bytes.Buffer)

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

	if err := json.NewEncoder(b).Encode(d); err != nil {
		return nil, errors.E(op, fmt.Errorf("error encoding migration status as json: %w", err))
	}

	return b, nil
}

type ProjectMigrationStatusOption func(applier *projectMigrationsStatus)

func newProjectMigrationsStatus(ec *cli.ExecutionContext) *projectMigrationsStatus {
	p := &projectMigrationsStatus{ec: ec}

	return p
}

func StatusAllDatabases() ProjectMigrationStatusOption {
	return func(p *projectMigrationsStatus) {
		p.allDatabases = true
	}
}

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Inspect the wrapped error (%w) — it names the exact type/field json could not marshal.
  2. Check any custom MarshalJSON implementations on the status struct and its nested types; ensure they never return errors for reachable states.
  3. Remove or replace unsupported field types (channels, functions, complex numbers) in the status payload; run go vet which flags json-incompatible types.
  4. If the error appears after a version upgrade, diff the status struct definition between releases.

Example fix

// before
type projectStatus struct {
	Progress chan int `json:"progress"` // unsupported by encoding/json
}

// after
type projectStatus struct {
	Progress int `json:"progress"`
}
Defensive patterns

Strategy: validation

Validate before calling

// Verify the status value is JSON-marshalable before encoding
if _, err := json.Marshal(d); err != nil {
    return nil, fmt.Errorf("status not serializable: %w", err)
}

Try / catch

if b, err := status.StatusJSON(...); err != nil && strings.Contains(err.Error(), "error encoding migration status") {
    // fall back to a minimal, always-marshalable status payload
}

Prevention

When it happens

Trigger: Calling StatusJSON (or any caller of json.NewEncoder(b).Encode(d)) where the migration status value d implements json.Marshaler and its MarshalJSON returns an error — e.g. a channel, function, or complex number field, or a nested type whose custom MarshalJSON fails.

Common situations: A new field of unsupported type (chan, func, complex, NaN/Inf float with certain encoders) added to the status struct; a custom MarshalJSON on a status sub-type that errors on unexpected state; rarely, API changes that altered the status payload shape between versions.

Related errors


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