hasura/graphql-engine · error

cannot build %s from project: %w

Error message

cannot build %s from project: %w

What it means

Thrown by projectmetadata buildMetadataMap when a metadata object cannot be reconstructed from the files on disk in the project's metadata directory. The %s is the object's Key() and %w the underlying build error — usually unmarshaling an invalid YAML/JSON metadata file for that subsystem.

Source

Thrown at cli/internal/projectmetadata/handler.go:177

		op       internalerrors.Op = "projectmetadata.Handler.buildMetadataMap"
		metadata                   = map[string]any{}
	)

	for _, object := range h.objects {
		objectMetadata, err := object.Build()
		if err != nil {
			if errors.Is(err, metadataobject.ErrMetadataFileNotFound) {
				h.logger.Debugf(
					"metadata file for %s was not found, assuming an empty file",
					object.Key(),
				)

				continue
			}

			return nil, internalerrors.E(
				op,
				fmt.Errorf("cannot build %s from project: %w", object.Key(), err),
			)
		}

		maps.Copy(metadata, objectMetadata)
	}

	return metadata, nil
}

// buildMetadata is a private function because we don't intend consumers of this package
// to use the returned result (metadataobject.Metadata) directly because they may assume that they can use
// json.Marshal to get JSON representation of the built metadata. But this assumption will not hold true because
// the underlying types might have instances of yaml.Node which is not friendly with a json.Marshal and can produce
// unexpected results. Rather to get a JSON / YAML form of built metadata make use of Handler.BuildYAMLMetadata and
// Handler.BuildJSONMetadata helper functions.
func (h *Handler) buildMetadata() (*Metadata, error) {
	var op internalerrors.Op = "projectmetadata.Handler.buildMetadata"

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Validate every file under metadata/ with a YAML/JSON linter and fix syntax errors
  2. Check the wrapped error to identify the offending file (the object key tells you which subsystem)
  3. Re-export metadata from the server into a fresh directory and diff against your project files
Defensive patterns

Strategy: validation

Validate before calling

func validateMetadataDir(dir string) error {
	return filepath.WalkDir(dir, func(p string, d fs.DirEntry, err error) error {
		if err != nil || d.IsDir() || (!strings.HasSuffix(p, ".yaml") && !strings.HasSuffix(p, ".json")) {
			return err
		}
		data, rerr := os.ReadFile(p)
		if rerr != nil {
			return rerr
		}
		if strings.HasSuffix(p, ".json") {
			return json.Unmarshal(data, &struct{}{})
		}
		return yaml.Unmarshal(data, &struct{}{})
	})
}

Try / catch

if _, err := handler.BuildMetadata(); err != nil {
	if strings.Contains(err.Error(), "cannot build") {
		// identify the subsystem key and validate its files
	}
}

Prevention

When it happens

Trigger: Calling buildMetadata (hasura metadata apply/EXPORT flows) when any file under metadata/ contains invalid YAML/JSON, references an entity that doesn't parse, or the file layout doesn't match the expected structure for that metadata kind.

Common situations: Hand-edited metadata files with syntax errors, files written by a different (older/newer) CLI version with a different schema, merge conflicts left unresolved in metadata/*.yaml.

Related errors


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