RocketChat/Rocket.Chat · warning · FormFetchError

error-agent-not-found

Error message

error-agent-not-found

What it means

Agent counterpart in RepliesForm: submit() looks up the chosen agentId in the already-loaded agents list (agents?.find(a => a.agentId === agentId)); if no entry matches while an agentId is set, it throws FormFetchError('error-agent-not-found'), and the catch triggers form validation to flag the agent field. This catches agents removed from the list (or department) between rendering and submitting.

Source

Thrown at apps/meteor/client/views/omnichannel/components/outboundMessage/components/OutboundMessageWizard/forms/RepliesForm/RepliesForm.tsx:104

	useEffect(() => {
		isErrorDepartment && trigger('departmentId');
		return () => clearErrors('departmentId');
	}, [clearErrors, isErrorDepartment, trigger]);

	const submit = useStableCallback(async ({ agentId, departmentId }: RepliesFormData) => {
		try {
			const agent = agents?.find((agent) => agent.agentId === agentId);

			// Wait if department or agent is still being fetched in background
			const updatedDepartment =
				departmentId && isFetchingDepartment ? await refetchDepartment().then((r) => r.data?.department) : department;

			if (departmentId && !updatedDepartment) {
				throw new FormFetchError('error-department-not-found');
			}

			if (agentId && !agent) {
				throw new FormFetchError('error-agent-not-found');
			}

			onSubmit({ departmentId, department: updatedDepartment, agentId, agent });
		} catch (error) {
			if (error instanceof FormFetchError) {
				trigger();
				return;
			}

			dispatchToastMessage({ type: 'error', message: t('Something_went_wrong') });
		}
	});

	return (
		<Form id={repliesFormId} onSubmit={handleSubmit(submit)} noValidate>
			<Scrollable vertical>
				<FieldGroup justifyContent='start' paddingInline={2}>
					<DepartmentField

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Re-select the agent from the current list for the chosen department.
  2. Ensure the agent is active and assigned to the selected department.
  3. Refetch/reset the agent selection when departmentId changes so the id always belongs to the current list.

Example fix

// before
const agent = agents?.find((agent) => agent.agentId === agentId);
if (agentId && !agent) {
  throw new FormFetchError('error-agent-not-found');
}

// after: reset stale selection when the agent list changes
useEffect(() => {
  if (agentId && !agents?.some((a) => a.agentId === agentId)) {
    setValue('agentId', undefined); // clear stale pick instead of erroring
  }
}, [agents, agentId, setValue]);
Defensive patterns

Strategy: validation

Validate before calling

const agent = agents?.find((a) => a.agentId === agentId);
if (agentId && !agent) {
  setValue('agentId', undefined); // clear stale selection before submit
}

Type guard

const isKnownAgent = (id: string | undefined, agents?: { agentId: string }[]): boolean =>
  !id || Boolean(agents?.some((a) => a.agentId === id));

Prevention

When it happens

Trigger: Submitting the replies step with an agentId that is not present in the fetched agents array for the selected department — agent unassigned/deactivated, list refetched and shorter, or a stale persisted agentId.

Common situations: Agent removed from the department or set inactive while the wizard was open; department changed so the agent list no longer contains the previously picked agent; drafts carrying old agent ids.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18). Data as JSON: /api/errors/42454b4b81b2e307. Report an issue: GitHub.