{"record":{"id":"c47cf7a8c0b5acad","repo":"hasura/graphql-engine","slug":"writing-metadata-to-file-w","errorCode":null,"errorMessage":"writing metadata to file: %w","messagePattern":"writing metadata to file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/commands/metadata_handlers.go","lineNumber":339,"sourceCode":"\t}\n\n\tvar metadataBytes []byte\n\n\tmetadataBytes, err = io.ReadAll(metadata)\n\tif err != nil {\n\t\treturn errors.E(op, fmt.Errorf(\"reading metadata from response: %w\", err))\n\t}\n\n\tif mode == cli.MetadataModeYAML {\n\t\tmetadataBytes, err = metadatautil.JSONToYAML(metadataBytes)\n\t\tif err != nil {\n\t\t\treturn errors.E(op, fmt.Errorf(\"parsing metadata to yaml: %w\", err))\n\t\t}\n\t}\n\n\terr = os.WriteFile(o.EC.MetadataFile, metadataBytes, os.ModePerm)\n\tif err != nil {\n\t\treturn errors.E(op, fmt.Errorf(\"writing metadata to file: %w\", err))\n\t}\n\n\treturn nil\n}\n\nfunc apply(o *MetadataApplyOptions, mode cli.MetadataMode) error {\n\tvar (\n\t\top                 errors.Op = \"commands.apply\"\n\t\tlocalMetadataBytes []byte\n\t\terr                error\n\t)\n\n\tlocalMetadataBytes, err = os.ReadFile(o.EC.MetadataFile)\n\tif err != nil {\n\t\treturn errors.E(op, fmt.Errorf(\"reading metadata file: %w\", err))\n\t}\n\n\tif o.DryRun {","sourceCodeStart":321,"sourceCodeEnd":357,"githubUrl":"https://github.com/hasura/graphql-engine/blob/724551b9ae87845594ef0408cff0e50eb6c90dc5/cli/commands/metadata_handlers.go#L321-L357","documentation":"The final step of `metadata export` writes the (possibly YAML-converted) metadata bytes to the configured metadata file (o.EC.MetadataFile) with os.WriteFile using os.ModePerm. This error means the local file write failed — the directory does not exist, permissions are insufficient, or the path points somewhere invalid.","triggerScenarios":"`metadata export` when os.WriteFile to the metadata file path fails: parent directory missing, read-only filesystem, permission denied on the directory, path is a directory, or disk full.","commonSituations":"Config file pointing to a metadata file location whose directory was never created (common in fresh checkouts); running the CLI in a container or CI where the working dir is read-only; metadata file path configured as a relative path resolving to an unexpected location; disk quota exhausted.","solutions":["Create the parent directory for the configured metadata file path (e.g. mkdir -p) and retry","Check write permissions on the directory and fix with chmod/chown if needed","Verify the metadata file path in config (it must be a file path, not a directory, in an existing directory)","If on a read-only filesystem (container/CI), write to /tmp or mount a writable volume and point the metadata file there"],"exampleFix":"# before\nhasura metadata export  # writing metadata to file: ... no such file or directory\n# after\nmkdir -p ./metadata && hasura metadata export  # with config metadata file ./metadata/metadata.[json|yaml]","handlingStrategy":"validation","validationCode":"// ensure the metadata file's directory exists and is writable before export\nif dir := filepath.Dir(ec.MetadataFile); dir != \"\" {\n  if _, err := os.Stat(dir); os.IsNotExist(err) {\n    os.MkdirAll(dir, 0o755)\n  }\n  if f, err := os.CreateTemp(dir, \"\"); err != nil {\n    return errors.New(\"metadata directory not writable\")\n  } else { f.Close(); os.Remove(f.Name()) }\n}","typeGuard":null,"tryCatchPattern":"if err := export(o, mode); err != nil {\n  if strings.Contains(err.Error(), \"writing metadata to file\") {\n    // fix directory permissions, mkdir -p, or change metadata file path\n  }\n}","preventionTips":["Commit the metadata directory (or a .gitkeep) to the repo","Verify the metadata file path in config on fresh checkouts","In CI, ensure the working directory is writable or redirect the metadata file"],"tags":["metadata","export","filesystem","permissions","cli","go"],"backgroundTag":"file-write-permission-denied","analyzedSha":"724551b9ae87845594ef0408cff0e50eb6c90dc5","analyzedAt":"2026-08-28T07:32:55.105Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}