666ghj/MiroFish · warning · Error
t('step5.selectAgentFirst')
Error message
t('step5.selectAgentFirst') What it means
Thrown at the top of sendToAgent when the user tries to chat with an individual agent but selectedAgent is falsy or selectedAgentIndex is null. It is a client-side precondition check: the chat target dropdown defaults to report_agent, and switching to a single agent requires clicking an agent in the list, which sets both refs. The throw is a guard, not a server condition.
Source
Thrown at frontend/src/components/Step5Interaction.vue:714
message: message,
chat_history: historyForApi
})
if (res.success && res.data) {
chatHistory.value.push({
role: 'assistant',
content: res.data.response || res.data.answer || t('step5.noResponse'),
timestamp: new Date().toISOString()
})
addLog(t('log.reportAgentReplied'))
} else {
throw new Error(res.error || t('step5.requestFailed'))
}
}
const sendToAgent = async (message) => {
if (!selectedAgent.value || selectedAgentIndex.value === null) {
throw new Error(t('step5.selectAgentFirst'))
}
addLog(t('log.sendToAgent', { name: selectedAgent.value.username, message: message.substring(0, 50) }))
// Build prompt with chat history
let prompt = message
if (chatHistory.value.length > 1) {
const historyContext = chatHistory.value
.slice(0, -1)
.slice(-6)
.map(msg => `${msg.role === 'user' ? '提问者' : '你'}:${msg.content}`)
.join('\n')
prompt = `以下是我们之前的对话:\n${historyContext}\n\n现在我的新问题是:${message}`
}
const res = await interviewAgents({
simulation_id: props.simulationId,
interviews: [{View on GitHub (pinned to b5b53acc57)
Solutions
- Select an agent in the agent list before sending, or switch the chat target back to report_agent.
- Disable the chat input/send button while chatTarget === 'agent' && !selectedAgent so the state is unreachable.
- When profiles are reloaded or the simulation changes, reset chatTarget to 'report_agent' and clear selectedAgent/selectedAgentIndex together.
- Validate selectedAgentIndex < profiles.length before sending, since the index is used to build the interview payload.
Example fix
// before
const sendToAgent = async (message) => {
if (!selectedAgent.value || selectedAgentIndex.value === null) {
throw new Error(t('step5.selectAgentFirst'))
}
// after - block at the UI boundary so the throw never fires
const canChatWithAgent = computed(() =>
chatTarget.value !== 'agent' || (selectedAgent.value !== null && selectedAgentIndex.value !== null)
)
// template: <input :disabled="!canChatWithAgent" ...>
const sendToAgent = async (message) => {
if (!selectedAgent.value || selectedAgentIndex.value === null) {
throw new Error(t('step5.selectAgentFirst'))
} Defensive patterns
Strategy: validation
Validate before calling
const canSendToAgent = computed(() => chatTarget.value !== 'agent' || (selectedAgent.value !== null && selectedAgentIndex.value !== null && selectedAgentIndex.value < profiles.value.length) ) // template: <textarea :disabled="chatTarget === 'agent' && !canSendToAgent">
Type guard
function hasSelectedAgent(sel, idx, profiles) {
return sel != null && idx !== null && Number.isInteger(idx) && idx >= 0 && idx < profiles.length
} Prevention
- Disable the chat input whenever chatTarget is 'agent' and no agent is selected.
- Reset chatTarget to 'report_agent' and clear selectedAgent/selectedAgentIndex together whenever profiles reload.
- Re-validate selectedAgentIndex against profiles.length before building the interview payload.
- Show a visible hint in agent mode until an agent is picked.
When it happens
Trigger: chatTarget is 'agent' (single-agent mode) but the user never clicked an agent profile; the selected agent was removed after profiles reloaded (selection not reset together); or a keyboard/enter submission races the click that sets selectedAgent before the watcher runs.
Common situations: UI lets the user type and press Enter before selecting an agent (send button/input not disabled in agent mode); agent list refresh clears selectedAgent but leaves chatTarget on 'agent'; profile array re-indexed after a simulation reload while an old index stayed selected.
Related errors
- res.error || t('step5.requestFailed')
- t('step5.noResponse')
- graph_id is required
- At least one text chunk is required
- batch_size must be between 1 and 350
AI-assisted analysis of 666ghj/MiroFish@b5b53acc57 (2026-08-14).
Data as JSON: /api/errors/5b61a0cd1e419b26.
Report an issue: GitHub.