langgenius/dify · error · BaseError
UsageInvalidFlag
UsageInvalidFlag
Error message
invalid --role "${opts.role}" What it means
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.
Source
Thrown at cli/src/commands/set/member/run.ts:47
readonly data: SetMemberOutput
readonly workspaceId: string
}
const ASSIGNABLE_ROLES = new Set(['normal', 'admin'])
export async function runSetMember(
opts: SetMemberOptions,
deps: SetMemberDeps,
): Promise<SetMemberResult> {
if (opts.memberId === undefined || opts.memberId === '') {
throw new BaseError({
code: ErrorCode.UsageMissingArg,
message: 'member id is required',
hint: 'pass it positionally: difyctl set member <member-id> --role <role>',
})
}
if (!ASSIGNABLE_ROLES.has(opts.role)) {
throw new BaseError({
code: ErrorCode.UsageInvalidFlag,
message: `invalid --role "${opts.role}"`,
hint: 'expected: normal | admin (ownership transfer is console-only)',
})
}
const env = deps.envLookup ?? ((k: string) => process.env[k])
const factory = deps.membersFactory ?? ((h: HttpClient) => new MembersClient(h))
const io = deps.io ?? nullStreams()
const cs = colorScheme(colorEnabled(io.isErrTTY))
const wsId = resolveWorkspaceId({
flag: opts.workspace,
env: env('DIFY_WORKSPACE_ID'),
active: deps.active,
})
await runWithSpinner({ io, label: `Updating role for ${opts.memberId}` }, () =>View on GitHub (pinned to ef8544b173)
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.
Example fix
// before $ difyctl set member <id> --role owner // after $ difyctl set member <id> --role admin
Defensive patterns
Strategy: validation
Validate before calling
const ASSIGNABLE_ROLES = new Set(['normal', 'admin'])
function isAssignableRole(role: string): boolean {
return ASSIGNABLE_ROLES.has(role)
} Type guard
type AssignableRole = 'normal' | 'admin'
function isAssignableRole(v: unknown): v is AssignableRole {
return v === 'normal' || v === 'admin'
} Prevention
- Use exactly lowercase `normal` or `admin`.
- Do ownership transfer in the web console — the CLI blocks it.
- Normalize role input to lowercase before invoking.
When it happens
Trigger: 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.
Common situations: User attempts ownership transfer via CLI (blocked by design); uses a role name from a different IAM system; passes uppercase or localized role labels.
Related errors
- UsageMissingArg
- usage_invalid_flag
- --action required: form has multiple user actions
- usage_invalid_flag
- UsageInvalidFlag
AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12).
Data as JSON: /api/errors/d46e106c6069c170.
Report an issue: GitHub.