FoundationAgents/MetaGPT · error · ValueError
Invalid tab_focus action {step}
Error message
Invalid tab_focus action {step} What it means
MetaGPT's execute_action raises this when a step classified as tab_focus fails to match r'tab_focus ?\[(\d+)\]'. Only a decimal page index inside brackets, e.g. 'tab_focus [0]', is accepted; anything else (non-numeric, missing brackets) fails.
Source
Thrown at metagpt/utils/a11y_tree.py:85
raise ValueError(f"Invalid scroll action {step}")
direction = match.group(1)
await scroll_page(page, direction)
elif func == "goto":
match = re.search(r"goto ?\[(.+)\]", step)
if not match:
raise ValueError(f"Invalid goto action {step}")
url = match.group(1)
await page.goto(url)
elif func == "new_tab":
page = await browser_ctx.new_page()
elif func == "go_back":
await page.go_back()
elif func == "go_forward":
await page.go_forward()
elif func == "tab_focus":
match = re.search(r"tab_focus ?\[(\d+)\]", step)
if not match:
raise ValueError(f"Invalid tab_focus action {step}")
page_number = int(match.group(1))
page = browser_ctx.pages[page_number]
await page.bring_to_front()
elif func == "close_tab":
await page.close()
if len(browser_ctx.pages) > 0:
page = browser_ctx.pages[-1]
else:
page = await browser_ctx.new_page()
elif func == "stop":
match = re.search(r'stop\(?"(.+)?"\)', step)
answer = match.group(1) if match else ""
return answer
else:
raise ValueError
await page.wait_for_load_state("domcontentloaded")
return page
View on GitHub (pinned to 11cdf466d0)
Solutions
- Use a zero-based integer index in brackets: 'tab_focus [0]'.
- Remember the index is passed straight to browser_ctx.pages[page_number], so index 0 is the first page.
- Log the step and the current len(browser_ctx.pages) to pick a valid index.
- Prompt the LLM with explicit tab_focus examples including the bracket syntax.
Example fix
# before await execute_action(page, 'tab_focus [1st]') # raises Invalid tab_focus action # after await execute_action(page, 'tab_focus [0]')
Defensive patterns
Strategy: validation
Validate before calling
import re
def valid_tab_focus_index(step: str, page_count: int):
m = re.search(r"tab_focus ?\[(\d+)\]", step)
if not m:
return None
idx = int(m.group(1))
return idx if 0 <= idx < page_count else None Try / catch
try:
await execute_action(page, step)
except (ValueError, IndexError) as e:
# invalid syntax or out-of-range page index: refresh tabs and re-ask Prevention
- Tell the LLM tab indices are zero-based and must fit the current tab list.
- Bound-check the index against len(browser_ctx.pages) — an in-range check also prevents the separate IndexError.
When it happens
Trigger: execute_action(page, 'tab_focus [first]') (non-numeric); 'tab_focus 0' without brackets; 'tab_focus [-1]' (\d+ rejects negative sign); LLM emitting 'tab_focus [1st tab]'.
Common situations: LLM refers to tabs by name or ordinal words instead of a zero-based integer index. Also triggered by off-by-one confusion: the value is used directly as browser_ctx.pages[page_number], so the model may emit human-style 1-based indices that are syntactically fine but semantically wrong — and any formatting slip raises this error.
Related errors
- Invalid press action {step}
- Invalid scroll action {step}
- Invalid goto action {step}
- Cannot find the answer phrase "{response}"
- Element {element_id} not found
AI-assisted analysis of FoundationAgents/MetaGPT@11cdf466d0 (2026-08-14).
Data as JSON: /api/errors/079a897faf5049cb.
Report an issue: GitHub.