{"record":{"id":"84c1b1ca50fe6db0","repo":"FlowiseAI/Flowise","slug":"invalid-human-input-type-expected-proceed-or-r","errorCode":null,"errorMessage":"Invalid human input type. Expected 'proceed' or 'reject', but got '${humanInput.type}'","messagePattern":"Invalid human input type\\. Expected 'proceed' or 'reject', but got '(.+?)'","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/components/nodes/agentflow/Agent/Agent.ts","lineNumber":1118,"sourceCode":"             * Only the inserted temporary messages contain base64 — other messages are untouched.\n             */\n            await addImageArtifactsToMessages(messages, options)\n\n            // Check if this is hummanInput for tool calls\n            const _humanInput = nodeData.inputs?.humanInput\n            const humanInput: IHumanInput = typeof _humanInput === 'string' ? JSON.parse(_humanInput) : _humanInput\n            const humanInputAction = options.humanInputAction\n            const iterationContext = options.iterationContext\n\n            // Track execution time\n            const startTime = Date.now()\n\n            // Get initial response from LLM\n            const sseStreamer: IServerSideEventStreamer | undefined = options.sseStreamer\n\n            if (humanInput) {\n                if (humanInput.type !== 'proceed' && humanInput.type !== 'reject') {\n                    throw new Error(`Invalid human input type. Expected 'proceed' or 'reject', but got '${humanInput.type}'`)\n                }\n                const result = await this.handleResumedToolCalls({\n                    humanInput,\n                    humanInputAction,\n                    messages,\n                    toolsInstance,\n                    sseStreamer,\n                    chatId,\n                    input,\n                    options,\n                    abortController,\n                    llmWithoutToolsBind,\n                    isStreamable,\n                    isLastNode,\n                    iterationContext,\n                    isStructuredOutput\n                })\n","sourceCodeStart":1100,"sourceCodeEnd":1136,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/components/nodes/agentflow/Agent/Agent.ts#L1100-L1136","documentation":"When the Agent node receives a humanInput (human-in-the-loop resume), it only accepts type 'proceed' or 'reject'. Any other type value aborts with this message before handleResumedToolCalls runs. The input is parsed from a JSON string or object stored in nodeData.inputs.humanInput.","triggerScenarios":"Submitting a resume payload with humanInput.type set to 'yes', 'approve', 'continue', undefined, or any string other than the two allowed; malformed resume message from a custom UI; replaying a stale humanInput object whose schema changed between versions.","commonSituations":"Custom chat UI sending its own action verbs; API client guessing the resume action format; version mismatch where older flows used different type names; button label-to-action mapping bug in the frontend.","solutions":["Send humanInput as { type: 'proceed' } to approve the pending tool call, or { type: 'reject' } to deny it.","Update the frontend resume handler to emit exactly 'proceed' or 'reject'.","Validate the payload against the IHumanInput schema before submitting.","If extending actions, coordinate a code change here first — the values are hardcoded."],"exampleFix":"// before\nconst humanInput = { type: 'approve', toolCallId: '...' }\n\n// after\nconst humanInput = { type: 'proceed', toolCallId: '...' }","handlingStrategy":"validation","validationCode":"const ALLOWED = new Set(['proceed', 'reject'])\nfunction normalizeHumanInput(raw) {\n  const hi = typeof raw === 'string' ? JSON.parse(raw) : raw\n  if (!hi || !ALLOWED.has(hi.type)) {\n    throw new Error(`humanInput.type must be one of ${[...ALLOWED].join(', ')}`)\n  }\n  return hi\n}","typeGuard":"function isHumanInput(v) {\n  return !!v && (v.type === 'proceed' || v.type === 'reject')\n}","tryCatchPattern":"try { await agent.run(nodeData, input, options) }\ncatch (e) {\n  if (/Invalid human input type/.test(e.message)) {\n    // re-send a valid proceed/reject payload\n  } else throw e\n}","preventionTips":["Use an enum/union type for humanInput.type in the API schema.","Frontend buttons must emit exactly 'proceed' or 'reject'.","Add a schema-validation middleware on the resume endpoint."],"tags":["agent","human-in-the-loop","validation","tool-calls"],"backgroundTag":null,"analyzedSha":"abe4a8601a058047b350c260676826e21dd14101","analyzedAt":"2026-08-12T16:04:40.823Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}