hasura/graphql-engine · error

cannot unmarshal local metadata to json: %w

Error message

cannot unmarshal local metadata to json: %w

What it means

While computing a metadata diff of type json between two project directories, the CLI converts each side's YAML metadata to JSON via convertYamlToJsonWithIndent; failure converting the new (local) side produces this error. The wrapped error is either a YAML parse error or a JSON indent failure on that side's metadata files.

Source

Thrown at cli/commands/metadata_diff.go:188

	newYaml, err := opts.projectMetadataHandler.BuildYAMLMetadata()
	if err != nil {
		return errors.E(op, err)
	}

	opts.projectMetadataHandler.SetMetadataObjects(
		projectmetadata.GetMetadataObjectsWithDir(opts.ec, opts.fromProjectDirectory),
	)

	oldYaml, err := opts.projectMetadataHandler.BuildYAMLMetadata()
	if err != nil {
		return errors.E(op, err)
	}

	switch opts.diffType {
	case DifftypeJSON:
		newJson, err := convertYamlToJsonWithIndent(newYaml)
		if err != nil {
			return errors.E(op, fmt.Errorf("cannot unmarshal local metadata to json: %w", err))
		}

		oldJson, err := convertYamlToJsonWithIndent(oldYaml)
		if err != nil {
			return errors.E(op, fmt.Errorf("cannot unmarshal server metadata to json: %w", err))
		}

		if err := printMyersDiff(
			string(newJson),
			string(oldJson),
			opts.toFriendlyName,
			opts.fromFriendlyName,
			opts.writer,
			opts.disableColor,
		); err != nil {
			return errors.E(op, err)
		}

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Locate and fix YAML syntax errors in the new directory's metadata files (hasura metadata export produces valid YAML as a baseline)
  2. Run yq or a YAML linter over the directory to pinpoint the malformed file
  3. Remove leftover git merge-conflict markers (<<<<<<< / >>>>>>>) from metadata files
  4. Regenerate metadata with `hasura metadata export` and re-apply your changes incrementally

Example fix

# before (tables.yaml with conflict markers)
<<<<<<< HEAD
- table: users
=======
- table: accounts
>>>>>>> main
# after (resolve the conflict)
- table: users
- table: accounts
Defensive patterns

Strategy: validation

Validate before calling

# Shell: lint YAML before diffing
for f in newdir/metadata/*.yaml; do yq '.' "$f" >/dev/null || exit 1; done
hasura metadata diff --type-of-diff json newdir olddir

Try / catch

// Go: pre-convert to catch bad YAML with a clear file name
for _, f := range files {
  if _, err := metadatautil.YAMLToJSON(read(f)); err != nil {
    return fmt.Errorf("%s: %w", f, err)
  }
}

Prevention

When it happens

Trigger: Running `hasura metadata diff --type-of-diff json <dir1> <dir2>` (or Diff between directories) where the first/new directory's YAML metadata contains invalid YAML — bad indentation, duplicate keys, tabs, or non-serializable constructs.

Common situations: Hand-edited metadata YAML with syntax errors, merge-conflict markers left in files, or a generated metadata directory where a file was truncated mid-write.

Related errors


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