{"record":{"id":"97f655436bec5f5b","repo":"hasura/graphql-engine","slug":"write-plugin-receipt-q-w","errorCode":null,"errorMessage":"write plugin receipt %q: %w","messagePattern":"write plugin receipt %q: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/plugins/plugins.go","lineNumber":481,"sourceCode":"\tplugin, err := c.ReadPluginFromFile(path)\n\tif err != nil {\n\t\treturn plugin, errors.E(op, err)\n\t}\n\n\treturn plugin, nil\n}\n\nfunc (c *Config) StoreManifest(plugin Plugin, dest string) error {\n\tvar op errors.Op = \"plugins.Config.StoreManifest\"\n\n\tyamlBytes, err := yaml.Marshal(plugin)\n\tif err != nil {\n\t\treturn errors.E(op, fmt.Errorf(\"convert to yaml: %w\", err))\n\t}\n\n\terr = os.WriteFile(dest, yamlBytes, 0o644)\n\tif err != nil {\n\t\treturn errors.E(op, fmt.Errorf(\"write plugin receipt %q: %w\", dest, err))\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":463,"sourceCodeEnd":486,"githubUrl":"https://github.com/hasura/graphql-engine/blob/724551b9ae87845594ef0408cff0e50eb6c90dc5/cli/plugins/plugins.go#L463-L486","documentation":"After successfully marshaling the plugin manifest to YAML, StoreManifest fails to write the bytes to the destination path (the plugin receipt file) with os.WriteFile. The error wraps the OS-level failure, so the message includes the exact destination path.","triggerScenarios":"Calling Config.Install or Config.Upgrade when dest (the receipt path, e.g. under IndexPluginsPath) is in a non-existent directory, is read-only, is owned by another user, or when the disk is full.","commonSituations":"Plugins index directory was deleted or never created; running the CLI under sudo previously so receipt files are root-owned; read-only filesystem such as a container image or NixOS store; ENOSPC.","solutions":["Ensure the parent directory of the receipt path exists (mkdir -p the plugins index dir) and is writable by the current user","Fix ownership: sudo chown -R $(whoami) on the CLI plugins index directory","Free disk space or remount the filesystem read-write, then retry install/upgrade"],"exampleFix":"# before\nmycli plugin install my-plugin\n# Error: write plugin receipt \"/root/.mycli/plugins/index/my-plugin.yaml\": permission denied\n\n# after\nmkdir -p ~/.mycli/plugins/index\nsudo chown -R $(whoami) ~/.mycli/plugins\nmycli plugin install my-plugin","handlingStrategy":"try-catch","validationCode":"if dir := filepath.Dir(dest); err := os.MkdirAll(dir, 0o755); err != nil { return err }\nif f, err := os.OpenFile(dest, os.O_WRONLY|os.O_CREATE, 0o644); err != nil { return err } ; f.Close()","typeGuard":null,"tryCatchPattern":"err := cfg.StoreManifest(p, dest)\nif err != nil {\n\tvar perr *fs.PathError\n\tif errors.As(err, &perr) && os.IsPermission(perr) {\n\t\t// fix ownership/permissions, then retry once\n\t}\n}","preventionTips":["Create the plugins index directory before installing","Never run the CLI with sudo unless you consistently do so, to avoid root-owned receipts","Check disk space before long install/upgrade sessions"],"tags":["plugins","filesystem","permissions","receipt"],"backgroundTag":"file-write-permission-denied","analyzedSha":"724551b9ae87845594ef0408cff0e50eb6c90dc5","analyzedAt":"2026-08-28T07:32:55.105Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}