langgenius/dify · error · BaseError

usage_invalid_flag

usage_invalid_flag

Error message

invalid --role "${opts.role}"

What it means

Raised by RagPipelineVariableApi.get (GET /rag/pipelines/{pipeline_id}/workflows/draft/variables/{variable_id}) when WorkflowDraftVariableService.get_variable returns None for variable_id. The variable genuinely does not exist. NotFoundError (from controllers.common.errors) maps to HTTP 404.

Source

Thrown at cli/src/commands/create/member/run.ts:47

  readonly data: InviteOutput
  readonly workspaceId: string
}

// `owner` is intentionally absent — ownership transfer is console-only.
const ASSIGNABLE_ROLES = new Set(['normal', 'admin'])

export async function runCreateMember(
  opts: CreateMemberOptions,
  deps: CreateMemberDeps,
): Promise<CreateMemberResult> {
  if (opts.email === undefined || opts.email === '') {
    throw new BaseError({
      code: ErrorCode.UsageMissingArg,
      message: '--email is required',
    })
  }
  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,
  })

  const response = await runWithSpinner({ io, label: `Inviting ${opts.email}` }, () =>

View on GitHub (pinned to ef8544b173)

Solutions

  1. List variables via GET /rag/pipelines/{pipeline_id}/workflows/draft/variables and use an id from the result.
  2. On the client, treat 404 as 'variable gone' and refresh the variable list.
  3. Avoid persisting variable_ids in long-lived deep links; re-resolve them from the collection endpoint.

Example fix

// before
const v = await get(`/rag/pipelines/${pipelineId}/workflows/draft/variables/${staleVarId}`);
// after
const { items } = await get(`/rag/pipelines/${pipelineId}/workflows/draft/variables`).then(r => r.json());
const v = items.find(x => x.id === varId) ?? null;
if (!v) { await reloadVariables(); return; }
Defensive patterns

Strategy: validation

Validate before calling

async function variableExists(client, pipelineId: string, variableId: string): Promise<boolean> {
  const r = await client.get(`/console/api/rag/pipelines/${pipelineId}/workflows/draft/variables`);
  const { items = [] } = await r.json();
  return items.some(v => v.id === variableId);
}

Type guard

function isKnownVariableId(id: string, known: Set<string>): boolean { return known.has(id); }

Try / catch

try {
  return await client.get(`/rag/pipelines/${pipelineId}/workflows/draft/variables/${variableId}`);
} catch (e) {
  if (e.response?.status === 404) { await reloadVariables(pipelineId); return null; }
  throw e;
}

Prevention

When it happens

Trigger: GET /console/api/rag/pipelines/{pipeline_id}/workflows/draft/variables/{variable_id} where the variable was deleted, never existed, or variable_id is a valid UUID with no matching row.

Common situations: Stale variable_id cached in the UI after the variable was removed; user navigates to a deep link for a deleted variable; concurrent deletion by another session.

Related errors


AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12). Data as JSON: /api/errors/1513299c18b69127. Report an issue: GitHub.