hasura/graphql-engine · error

creating metadata file %s failed: %w

Error message

creating metadata file %s failed: %w

What it means

Thrown by projectmetadata.WriteMetadata when afero.WriteFile cannot create or write one of the metadata files it is exporting to disk. The %s names the target file path and %w the underlying filesystem error (permission denied, missing parent directory, read-only filesystem, etc.).

Source

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

func (h *Handler) SetMetadataObjects(objects metadataobject.Objects) {
	h.objects = objects
}

// WriteMetadata writes the files in the metadata folder.
func (h *Handler) WriteMetadata(files map[string][]byte) error {
	var op internalerrors.Op = "projectmetadata.Handler.WriteMetadata"

	for name, content := range files {
		fs := afero.NewOsFs()
		if err := fs.MkdirAll(filepath.Dir(name), os.ModePerm); err != nil {
			return internalerrors.E(op, err)
		}

		err := afero.WriteFile(fs, name, content, 0o644)
		if err != nil {
			return internalerrors.E(
				op,
				fmt.Errorf("creating metadata file %s failed: %w", name, err),
			)
		}
	}

	return nil
}

func (h *Handler) ExportMetadata() (map[string][]byte, error) {
	var op internalerrors.Op = "projectmetadata.Handler.ExportMetadata"

	metadataFiles := make(map[string][]byte)

	var (
		resp io.Reader
		err  error
	)

	resp, err = h.v1MetadataOps.ExportMetadata()

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Check the file path in the message and create its parent directory (mkdir -p metadata) or grant write permission (chmod/chown)
  2. Verify the filesystem is writable and not out of space (df -h)
  3. Run the command from a directory the current user owns, especially in CI containers

Example fix

// before: output dir missing
err := handler.WriteMetadata(exportDir) // -> creating metadata file metadata/tables.yaml failed: open ...: no such file or directory

// after: ensure dir exists first
if err := os.MkdirAll(exportDir, 0o755); err != nil { return err }
err := handler.WriteMetadata(exportDir)
Defensive patterns

Strategy: validation

Validate before calling

func ensureWritableDir(fs afero.Fs, dir string) error {
	if err := fs.MkdirAll(dir, 0o755); err != nil {
		return err
	}
	info, err := fs.Stat(dir)
	if err != nil || !info.IsDir() {
		return fmt.Errorf("%s is not a directory", dir)
	}
	probe := filepath.Join(dir, ".probe")
	if err := afero.WriteFile(fs, probe, []byte("x"), 0o644); err != nil {
		return fmt.Errorf("directory %s not writable: %w", dir, err)
	}
	return fs.Remove(probe)
}

Try / catch

if err := handler.WriteMetadata(dir); err != nil {
	if strings.Contains(err.Error(), "creating metadata file") {
		// prompt user to fix permissions / free disk, then retry
	}
}

Prevention

When it happens

Trigger: Calling WriteMetadata when the output directory or its parent does not exist, the process lacks write permission on the target path, the disk is full, or the filesystem is read-only (e.g. CI container, mounted volume).

Common situations: Running `hasura metadata export` in a directory where metadata/ cannot be created, CI pipelines running as a non-root user without write access to the workspace, a full disk, or a read-only mount.

Related errors


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