{"record":{"id":"759eab003138551f","repo":"t8y2/dbx","slug":"etcd-invalid-access","errorCode":"ETCD_INVALID_ACCESS","errorMessage":"ETCD_INVALID_ACCESS: access must be READ, WRITE, or READWRITE, got %s","messagePattern":"ETCD_INVALID_ACCESS: access must be READ, WRITE, or READWRITE, got (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agents/drivers/etcd-go/auth.go","lineNumber":443,"sourceCode":"\t\taccess, err := permissionType(stringOrDefault(params, \"access\", \"\"))\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif _, err := client.Auth.RoleGrantPermission(ctx, role, key, rangeEnd, access); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t} else {\n\t\tif _, err := client.Auth.RoleRevokePermission(ctx, role, key, rangeEnd); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn map[string]bool{\"updated\": true}, nil\n}\n\nfunc permissionType(access string) (clientv3.PermissionType, error) {\n\tpermission, err := clientv3.StrToPermissionType(strings.ToUpper(access))\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"ETCD_INVALID_ACCESS: access must be READ, WRITE, or READWRITE, got %s\", access)\n\t}\n\treturn permission, nil\n}\n","sourceCodeStart":425,"sourceCodeEnd":447,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/etcd-go/auth.go#L425-L447","documentation":"permissionType validates the access string for etcd role permission grants by passing it to clientv3.StrToPermissionType. Only READ, WRITE and READWRITE are valid; any other value (case-insensitive, since it upper-cases first) fails conversion and yields this ETCD_INVALID_ACCESS coded error.","triggerScenarios":"Calling AuthRolePermissionGrant (via authRolePermission) with access values like \"readwrite \" with whitespace, \"rw\", \"all\", \"read-only\", or lowercase variants of unsupported words — anything StrToPermissionType rejects.","commonSituations":"Config files or IaC granting permissions with shorthand values (\"rw\", \"all\"); trailing whitespace or BOM in YAML/JSON config; porting etcdctl examples that use different permission vocabulary; older configs written for other auth systems.","solutions":["Change the access value to exactly READ, WRITE, or READWRITE (case-insensitive)","Trim whitespace and check for hidden characters in config-sourced access strings","Map unsupported shorthands (e.g. \"all\") to the closest valid value or issue separate READ and WRITE grants","Validate the access string before calling the grant API"],"exampleFix":"// before\nsrv.AuthRolePermissionGrant(ctx, \"app-role\", key, \"rw\")\n// after\nsrv.AuthRolePermissionGrant(ctx, \"app-role\", key, \"READWRITE\")","handlingStrategy":"validation","validationCode":"func validAccess(access string) bool {\n\tswitch strings.ToUpper(strings.TrimSpace(access)) {\n\tcase \"READ\", \"WRITE\", \"READWRITE\":\n\t\treturn true\n\t}\n\treturn false\n}","typeGuard":"func isPermissionType(s string) bool {\n\t_, err := clientv3.StrToPermissionType(strings.ToUpper(strings.TrimSpace(s)))\n\treturn err == nil\n}","tryCatchPattern":"if err := grantPermission(ctx, role, key, access); err != nil {\n\tif strings.Contains(err.Error(), \"ETCD_INVALID_ACCESS\") {\n\t\treturn fmt.Errorf(\"invalid access %q: must be READ, WRITE or READWRITE\", access)\n\t}\n\treturn err\n}","preventionTips":["Validate access strings against {READ, WRITE, READWRITE} before calling grant APIs","Trim and normalize config values (ToUpper + TrimSpace) loaded from YAML/JSON","Replace shorthand values like \"rw\" or \"all\" with the canonical permission names in configs","Add schema/enum validation for access fields in IaC and config tooling"],"tags":["etcd","auth","permissions","validation"],"backgroundTag":"invalid-permission-type","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}