{"record":{"id":"fa8c68888e062736","repo":"langgenius/dify","slug":"action-required-form-has-multiple-user-actions","errorCode":null,"errorMessage":"--action required: form has multiple user actions","messagePattern":"--action required: form has multiple user actions","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"cli/src/commands/resume/app/run.ts","lineNumber":60,"sourceCode":"  const apps = selectAppReader(deps.active, deps.http)\n  const meta = new AppMetaClient({ apps, host: deps.host, cache: deps.cache })\n  const m = await meta.get(opts.appId, [FieldInfo])\n  const mode = m.info?.mode ?? RUN_MODES.Workflow\n\n  const runClient = new AppRunClient(deps.http)\n  const exit = deps.exit ?? processExit\n\n  let action = opts.action\n  if (action === undefined) {\n    const formResp = await deps.http.get<{ user_actions: { id: string }[] }>(\n      `apps/${encodeURIComponent(opts.appId)}/human-input-forms/${encodeURIComponent(opts.formToken)}`,\n    )\n    if (formResp.user_actions.length === 1) {\n      action = formResp.user_actions[0]?.id ?? ''\n    } else if (formResp.user_actions.length === 0) {\n      action = ''\n    } else {\n      throw new Error('--action required: form has multiple user actions')\n    }\n  }\n\n  const inputs = await resolveInputs(opts.inputsJson, opts.inputsFile, opts.inputs)\n  await runClient.submitHumanInput(opts.appId, opts.formToken, action, inputs)\n\n  const format = opts.format ?? ''\n  const isText = TEXT_FORMATS.has(format)\n\n  if (isText) {\n    const cs = colorScheme(colorEnabled(deps.io.isErrTTY))\n    deps.io.err.write(`${cs.successIcon()} ${cs.bold('form submitted')}\\n`)\n    deps.io.err.write(`  ${cs.dim('workflow execution resumed')}\\n`)\n  }\n  const livePrint = opts.stream === true\n\n  const adaptedRunClient = {\n    runStream: (_appId: string, _body: unknown, streamOpts?: { signal?: AbortSignal }) =>","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/langgenius/dify/blob/ef8544b173fd6cd7a8e71df2cab576e52bebbfbc/cli/src/commands/resume/app/run.ts#L42-L78","documentation":"Thrown by `resume app` (cli/src/commands/resume/app/run.ts:60) as a plain `Error` (no BaseError/code) when `--action` is omitted and the fetched human-input form at `apps/{appId}/human-input-forms/{formToken}` returns more than one `user_actions` entry. The CLI cannot disambiguate which action to submit, so it aborts before calling `submitHumanInput`. Note: unlike most errors here it lacks a `code`, so it surfaces as a generic exit-1.","triggerScenarios":"Calling `difyctl resume app` without `--action` on a form that offers multiple buttons (e.g. Approve + Reject, or Submit + Cancel). The form fetch returns `user_actions.length >= 2`, hitting the `else` branch at line 59-61.","commonSituations":"A workflow with a human-in-the-loop approval node that branches on multiple outcomes; the form was designed with several action buttons; the caller assumed auto-selection (single action) but the app author added a second option.","solutions":["Pass `--action <action-id>` using one of the IDs from the form's `user_actions` array.","Inspect the form first: `difyctl describe` or GET `apps/{appId}/human-input-forms/{formToken}` to list valid action IDs.","If only one action is intended, update the workflow form to expose a single user action so auto-selection applies."],"exampleFix":"// before\n$ difyctl resume app --app <uuid> --form-token <tok>\n// after\n$ difyctl resume app --app <uuid> --form-token <tok> --action approve","handlingStrategy":"validation","validationCode":"// Before calling resumeApp, fetch the form and pass --action explicitly.\nconst form = await http.get<{ user_actions: { id: string }[] }>(\n  `apps/${appId}/human-input-forms/${formToken}`,\n)\nif (form.user_actions.length !== 1 && !opts.action) {\n  throw new Error(`pass --action: ${form.user_actions.map(a => a.id).join(', ')}`)\n}","typeGuard":null,"tryCatchPattern":"try {\n  await resumeApp(opts, deps)\n} catch (err) {\n  if (err instanceof Error && /--action required/.test(err.message)) {\n    // list actions from the form, then retry with opts.action set\n  }\n  throw err\n}","preventionTips":["For forms with multiple buttons, always pass `--action <id>`.","Inspect the form's `user_actions` before resuming to know valid action IDs.","Design workflow forms with a single action when auto-selection is desired."],"tags":["cli","human-input","workflow","difyctl","typescript"],"backgroundTag":null,"analyzedSha":"ef8544b173fd6cd7a8e71df2cab576e52bebbfbc","analyzedAt":"2026-08-12T05:15:17.394Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}