{"record":{"id":"d46e106c6069c170","repo":"langgenius/dify","slug":"usageinvalidflag-d46e10","errorCode":"UsageInvalidFlag","errorMessage":"invalid --role \"${opts.role}\"","messagePattern":"invalid --role \"(.+?)\"","errorType":"error_code","errorClass":"BaseError","httpStatus":null,"severity":"error","filePath":"cli/src/commands/set/member/run.ts","lineNumber":47,"sourceCode":"  readonly data: SetMemberOutput\n  readonly workspaceId: string\n}\n\nconst ASSIGNABLE_ROLES = new Set(['normal', 'admin'])\n\nexport async function runSetMember(\n  opts: SetMemberOptions,\n  deps: SetMemberDeps,\n): Promise<SetMemberResult> {\n  if (opts.memberId === undefined || opts.memberId === '') {\n    throw new BaseError({\n      code: ErrorCode.UsageMissingArg,\n      message: 'member id is required',\n      hint: 'pass it positionally: difyctl set member <member-id> --role <role>',\n    })\n  }\n  if (!ASSIGNABLE_ROLES.has(opts.role)) {\n    throw new BaseError({\n      code: ErrorCode.UsageInvalidFlag,\n      message: `invalid --role \"${opts.role}\"`,\n      hint: 'expected: normal | admin (ownership transfer is console-only)',\n    })\n  }\n\n  const env = deps.envLookup ?? ((k: string) => process.env[k])\n  const factory = deps.membersFactory ?? ((h: HttpClient) => new MembersClient(h))\n  const io = deps.io ?? nullStreams()\n  const cs = colorScheme(colorEnabled(io.isErrTTY))\n\n  const wsId = resolveWorkspaceId({\n    flag: opts.workspace,\n    env: env('DIFY_WORKSPACE_ID'),\n    active: deps.active,\n  })\n\n  await runWithSpinner({ io, label: `Updating role for ${opts.memberId}` }, () =>","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/langgenius/dify/blob/ef8544b173fd6cd7a8e71df2cab576e52bebbfbc/cli/src/commands/set/member/run.ts#L29-L65","documentation":"Thrown by `runSetMember` (set/member/run.ts:47) as `usage_invalid_flag` (exit 2) when `opts.role` is not in the assignable set `{normal, admin}`. Ownership transfer is intentionally excluded (console-only) per the hint. The check uses an exact-match `Set.has`, so case variants like `Admin` or aliases like `owner`/`member` are rejected.","triggerScenarios":"Passing `--role owner`, `--role member`, `--role Admin` (wrong case), `--role editor`, or any value outside `{normal, admin}`. Fires at line 46 after the memberId check.","commonSituations":"User attempts ownership transfer via CLI (blocked by design); uses a role name from a different IAM system; passes uppercase or localized role labels.","solutions":["Use exactly `--role normal` or `--role admin` (lowercase).","For ownership transfer, perform it in the Dify web console (CLI does not support it).","Double-check the role vocabulary against the workspace members API."],"exampleFix":"// before\n$ difyctl set member <id> --role owner\n// after\n$ difyctl set member <id> --role admin","handlingStrategy":"validation","validationCode":"const ASSIGNABLE_ROLES = new Set(['normal', 'admin'])\nfunction isAssignableRole(role: string): boolean {\n  return ASSIGNABLE_ROLES.has(role)\n}","typeGuard":"type AssignableRole = 'normal' | 'admin'\nfunction isAssignableRole(v: unknown): v is AssignableRole {\n  return v === 'normal' || v === 'admin'\n}","tryCatchPattern":null,"preventionTips":["Use exactly lowercase `normal` or `admin`.","Do ownership transfer in the web console — the CLI blocks it.","Normalize role input to lowercase before invoking."],"tags":["cli","workspace","members","roles","difyctl","typescript"],"backgroundTag":null,"analyzedSha":"ef8544b173fd6cd7a8e71df2cab576e52bebbfbc","analyzedAt":"2026-08-12T05:15:17.394Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}