{"record":{"id":"5f674f814668fc86","repo":"hasura/graphql-engine","slug":"error-in-writing-s-file-w","errorCode":null,"errorMessage":"error in writing %s file: %w","messagePattern":"error in writing (.+?) file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/internal/metadataobject/actions/actions.go","lineNumber":241,"sourceCode":"\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tvar common types.Common\n\n\tcommon.Actions = sdlFromResp.Actions\n\tcommon.CustomTypes = sdlFromResp.Types\n\tcommon.SetExportDefault()\n\t// write actions.yaml\n\tcommonByt, err := yaml.Marshal(common)\n\tif err != nil {\n\t\treturn errors.E(op, fmt.Errorf(\"error in marshalling common: %w\", err))\n\t}\n\n\terr = os.WriteFile(filepath.Join(a.MetadataDir, a.Filename()), commonByt, 0o644)\n\tif err != nil {\n\t\treturn errors.E(op, fmt.Errorf(\"error in writing %s file: %w\", a.Filename(), err))\n\t}\n\n\terr = os.WriteFile(filepath.Join(a.MetadataDir, graphqlFileName), data, 0o644)\n\tif err != nil {\n\t\treturn errors.E(op, fmt.Errorf(\"error in writing %s file: %w\", graphqlFileName, err))\n\t}\n\n\treturn nil\n}\n\nfunc (a *ActionConfig) Codegen(name string, derivePld types.DerivePayload) error {\n\tvar op errors.Op = \"actions.ActionConfig.Codegen\"\n\n\terr := a.ensureCliExt()\n\tdefer a.cleanupCliExt()\n\n\tif err != nil {\n\t\treturn errors.E(op, err)","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/hasura/graphql-engine/blob/724551b9ae87845594ef0408cff0e50eb6c90dc5/cli/internal/metadataobject/actions/actions.go#L223-L259","documentation":"Create cannot write the merged actions.yaml file into the metadata directory (a.MetadataDir). os.WriteFile failed — the wrapped error names the OS-level cause (missing directory, permission denied, disk full, path is a directory).","triggerScenarios":"Running actions create/export when the metadata directory does not exist, is read-only, or the process lacks write permission; actions.yaml path occupied by a directory; no disk space.","commonSituations":"Running the CLI in CI as a non-root user against a checked-out repo with restrictive permissions; incorrect --metadata-dir flag pointing to a nonexistent path; Docker container with a read-only mount.","solutions":["Check the wrapped error for the OS cause (ENOENT vs EACCES)","mkdir -p the metadata directory or fix the --metadata-dir /HASURA_METADATA_DIRECTORY setting","chmod/chown the directory so the current user can write, or run with appropriate privileges","Free disk space or remount the volume read-write if in a container"],"exampleFix":"# before\nhasura actions codegen ... # metadata dir missing\n# after\nmkdir -p metadata/actions\nhasura actions codegen ...","handlingStrategy":"validation","validationCode":"// Ensure the metadata dir is writable before Create\ninfo, err := os.Stat(metadataDir)\nif err != nil || !info.IsDir() {\n    os.MkdirAll(metadataDir, 0o755)\n}\nif f, err := os.CreateTemp(metadataDir, \".w\"); err == nil {\n    f.Close()\n    os.Remove(f.Name())\n} else {\n    return fmt.Errorf(\"metadata dir not writable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := actionCfg.Create(ctx); err != nil {\n    if pe := new(fs.PathError); errors.As(err, &pe) {\n        // handle OS-level write failure (permissions, missing dir)\n    }\n}","preventionTips":["Pre-create the metadata directory in setup scripts","Run CI with a user that owns the checkout","Avoid read-only mounts for the metadata dir"],"tags":["filesystem","permissions","actions","write-file"],"backgroundTag":"file-write-permission-denied","analyzedSha":"724551b9ae87845594ef0408cff0e50eb6c90dc5","analyzedAt":"2026-08-28T07:32:55.105Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}