OpenManus enforces no token limit by default. Its own ceiling is max_input_tokens, which app/config.py declares as Optional with a default of None and the description "Maximum input tokens to use across all requests (None for unlimited)", and which appears in no shipped config example. So a stock install never raises a token-limit error of its own — whatever you hit came from the provider. When you do set it, it behaves in two ways people do not expect, and a defect present in current main makes it fail slowly instead of fast.
The other error this page covers, Error: Unknown tool 'BrowserUseTool', is not a live bug at all. The class it names was deleted from OpenManus on August 15, 2026, and the default Manus agent on current main registers no browser tool locally. Neither symptom is an API key, endpoint or provider problem, and repointing base_url fixes neither.
One framing note before any of it. There is no OpenManus version to cite: the only three tags, v0.1.0, v0.2.0 and v0.3.0, were all published within 34 seconds of each other on April 10, 2025, and nothing has been tagged since, so everyone runs untagged main. The canonical repository is FoundationAgents/OpenManus — not archived, MIT, 58,371 stars, last pushed August 22, 2026 (GitHub API, September 21, 2026). The old mannaandpoem/OpenManus path is now a stub README saying the project moved, so file paths and line numbers quoted from 2025 tutorials point at code that is no longer there. Everything below was read at source on branch main on September 21, 2026 and none of it was executed.
Which of the four messages you actually have
| What you see | Who prints it | What it means |
|---|---|---|
Maximum token limit reached, cannot continue execution: Request may exceed input token limit (Current: …, Needed: …, Max: …) | OpenManus, app/agent/toolcall.py | Your own max_input_tokens ceiling for the run was reached. No request was sent |
| A context-length or token error naming the model | Your provider, surfaced through OpenAIError | The request exceeded the model's context window or the endpoint's own limit. Unrelated to OpenManus's ceiling |
Error: Unknown tool 'X' | OpenManus, app/agent/toolcall.py lines 179–181 | The model named a tool absent from available_tools.tool_map. Returned as a tool result, so the loop continues and burns a step |
Failed to connect to Browser Use CLI 3.0: … | OpenManus, app/agent/manus.py line 99 | The default browser MCP server did not start. The run continues: the Manus agent keeps its four local tools, plus any other MCP servers you configured |
The dispatch that produces the third row is three lines, and it is unchanged by the 2026 browser rewrite: name = command.function.name, then if name not in self.available_tools.tool_map: return f"Error: Unknown tool '{name}'". Nothing in it is specific to browsers, so the same string appears for any tool a model invents.
The token limit is opt-in, cumulative, and approximate
Three different numbers get called "the token limit", and the error message only ever concerns one of them.
| Setting | What it bounds | Default | In the shipped example? |
|---|---|---|---|
max_tokens | One response | 4096 in code | Yes — set to 8192 |
max_input_tokens | Cumulative input across the whole run | None, meaning unlimited | No. You add it by hand or it does not apply |
| The model's context window | One request, at the provider | The model's own | Not an OpenManus setting at all |
The second row is the one that surprises people. LLM.check_token_limit() in app/llm.py returns (self.total_input_tokens + input_tokens) <= self.max_input_tokens — a running total for the session, not a check against one request. So a long agent run trips it through accumulation even when every individual request is small, and the error text spells the arithmetic out: current, needed, max. The default Manus agent sets max_steps = 20, and each step resends the conversation so far, so the cumulative figure climbs faster than the step count does.
The count is also OpenManus's own estimate. LLM.__init__ calls tiktoken.encoding_for_model(self.model) and falls back to cl100k_base on a KeyError, so for any model ID tiktoken has no preset for — a Claude or Gemini ID, or a gateway-namespaced one — the budget being enforced is an approximation rather than the provider's count.
# config/config.toml
[llm]
model = "claude-sonnet-4-6"
base_url = "https://api.kunavo.com/v1"
api_key = "sk-kn-..."
# The RESPONSE cap. Ships as 8192 in config.example.toml; the code default is 4096.
max_tokens = 8192
# The CUMULATIVE INPUT budget for the whole run. Absent from every shipped
# example, and None in code — so a stock install enforces no ceiling at all.
max_input_tokens = 400000What a ceiling is worth in money
Because max_input_tokens bounds cumulative input, it converts directly into a cost ceiling for the input side of one run. The figures below are illustrative token arithmetic on the stated ceiling, not a measured task cost and not a bill ceiling: they price the input tokens the setting caps, at live Kunavo catalog rates per million. Output is not covered by that setting at all — the last column prices one response at the max_tokens = 8192 the example config ships, and a twenty-step run can produce twenty of them.
| Model | Input / output per 1M | Input at a 100,000 ceiling | Input at a 400,000 ceiling | One 8,192-token response |
|---|---|---|---|---|
| Claude Haiku 4.5 | $0.40 / $2.00 | $0.040 | $0.160 | $0.016 |
| Gemini 3.8 Flash | $0.525 / $2.625 | $0.053 | $0.210 | $0.022 |
| GPT-5.6 Luna | $0.07 / $0.42 | $0.007 | $0.028 | $0.003 |
| Claude Sonnet 4.6 | $1.20 / $6.00 | $0.120 | $0.480 | $0.049 |
| Claude Opus 5 | $2.00 / $10.00 | $0.200 | $0.800 | $0.082 |
Two readings. A ceiling is a stop, not a budget: it tells you the most the input side of a run can cost, and says nothing about whether the task finished. And because OpenManus counts with tiktoken, the ceiling it enforces and the tokens your provider bills are two different measurements — set the number to bound a runaway loop, then reconcile against what your account actually recorded. Kunavo's catalog amount is a billing floor rather than a cap: when the upstream reports its charge, the bill is the greater of catalog cost and upstream cost times the applicable markup. The minimum Kunavo top-up is $10 in prepaid credit, a funding minimum rather than a task fee or a subscription — see billing details.
Why the token error arrives late
This is a defect you can read in current main, and it is the reason a token-limit failure feels like a hang. All three @retry decorators in app/llm.py — on ask, ask_with_images and ask_tool — are written identically:
| What the decorator says | What it matches | Consequence |
|---|---|---|
Trailing comment: # Don't retry TokenLimitExceeded | retry_if_exception_type((OpenAIError, Exception, ValueError)) | TokenLimitExceeded subclasses OpenManusError, which subclasses Exception — so the bare Exception entry matches it |
Raise site comment: # Raise a special exception that won't be retried | stop_after_attempt(6), wait_random_exponential(min=1, max=60) | Up to six attempts with exponential backoff before the error surfaces, each recomputing the same failing total |
The agent loop downstream confirms the shape rather than contradicting it. app/agent/toolcall.py catches the exception and tests isinstance(e.__cause__, TokenLimitExceeded) — that __cause__ unwrapping is how a tenacity RetryError arrives, and its own log line reads "Token limit error (from RetryError)". Only then does it add the user-visible "Maximum token limit reached, cannot continue execution" message and set the agent state to finished. In other words the consuming code already assumes the retry the decorator comment says does not happen.
There is no merged fix. PR #1348, titled "fix: prevent needless retry of TokenLimitExceeded and fix search engine fallback", was closed unmerged on August 10, 2026; its resubmission #1407 was still open and unmerged on September 21, 2026. A related context-overflow PR, #1391, "add tool description token budget to prevent context overflow", was closed unmerged on August 18, 2026. Why the maintainers closed them was not read here, only that they are unmerged. The historical report, issue #779 "hitting token limit" from March 17, 2025, was closed on September 17, 2026 by an inactivity bot with state_reason: not_planned — a timeout, not a resolution. Until one of those lands, the practical mitigations are to leave max_input_tokens unset and let the provider reject oversized requests, or to set it and accept the delay.
Unknown tool 'BrowserUseTool' is an error from a version that no longer exists
Issue #789, "Result: Error: Unknown tool 'BrowserUseTool'", was opened on March 18, 2025 and was still open on September 21, 2026, labelled inactive. Its cause was never an endpoint or a key. The reporter's own log shows the model emitting the Python class name, BrowserUseTool, where the registered tool name was browser_use — and the very next step of the same run dispatching cleanly once it called browser_use. The log they pasted ends at "Activating tool: 'browser_use'", and their closing line is the whole diagnosis: "BrowserUseTool seems not work, but browser_use can". The only advice any commenter gave was to try a stronger model, which is the right shape of answer for a tool-calling-fidelity problem.
That diagnosis does not transfer to current main, because there is no longer any tool named browser_use to get right. On August 15, 2026 commits ab8dfe43 ("feat(browser): use Browser Use CLI 3.0") and 05c5bbb1 ("refactor(browser): use CLI 3.0 MCP server") deleted the local browser tool. A directory listing of app/tool/ on main contains no browser_use_tool.py, and the only occurrence of the string BrowserUseTool left in the tree is a commented-out line in app/agent/sandbox_agent.py.
| March 2025 code (issue #789) | Current main, read September 21, 2026 | |
|---|---|---|
| Browser tool | Local class in app/tool/browser_use_tool.py | Deleted. On the default Manus agent, an out-of-process MCP server started as uvx browser-use --cli-mcp |
| Registered name | browser_use | browser_exec and browser_screenshot, per the README |
| Locally registered tools on the Manus agent | Included the browser tool | PythonExecute, StrReplaceEditor, AskHuman, Terminate — browser tools arrive over MCP |
| Dependency pin | Pinned in requirements.txt | No browser-use entry; fetched at run time by uvx, so the browser stack floats independently of your checkout |
| Credentials | Your model key | Local mode needs no key. Cloud mode is a separate Browser Use account with its own environment variables |
| Off switch | Remove the tool | OPENMANUS_DISABLE_BROWSER_USE=1 |
So the fix for this exact string today is to update your checkout, and to stop reasoning from tutorials written against the old repository path. One caveat worth stating rather than guessing at: when the MCP connection fails, app/agent/manus.py logs Failed to connect to Browser Use CLI 3.0 and continues with the four local tools, which leaves the model able to name a browser tool that is not registered. Whether that produces an Unknown tool message in practice, and under which name, was not observed here — treat it as a place to look, not as a documented symptom. Note also that requirements.txt pins uv>=0.6.0; whether a normal install puts uvx on your PATH was not verified.
One thing that search will still turn up, and that the paragraphs above are deliberately not claiming: the repository does contain browser code that the default path never loads. The separate Daytona-sandbox entry point sandbox_main.py builds a SandboxManus agent that registers SandboxBrowserTool from app/tool/sandbox/sb_browser_tool.py as a local tool — under the name sandbox_browser, not browser_use. So "no local browser tool" is a statement about the default Manus agent you get from main.py, not about the whole tree.
One name to keep apart while searching: OpenManus/OpenManus-RL is a separate repository in a separate organisation, a reinforcement-learning research project rather than a version of the agent runtime, and its file layout has nothing to say about either error.
What a different API endpoint does and does not change
Both symptoms above are produced inside OpenManus, so the honest answer to "will another provider fix this" is no. What an endpoint choice does affect is a nearby set of failures that are easy to misread as these two.
| Failure | Endpoint-shaped? | What to check first |
|---|---|---|
| OpenManus's own token-limit message | No — raised before any request is sent | Your max_input_tokens value, and whether you meant to set one |
Unknown tool | No — the model named something unregistered | Which tools that agent registers, and whether the model is strong enough at tool calling |
| A provider context-length rejection | Yes | The model's context window, and max_tokens against it |
| An authentication or model-not-found error on a first run | Yes | The shipped example still names a Claude ID Anthropic retired on February 19, 2026 — covered in OpenManus pricing and API setup |
A 400 on temperature | Yes | OpenManus sends temperature on every request outside its two hardcoded reasoning IDs, and ships temperature = 0.0 |
| Screenshots silently never reaching the model | Partly | Vision is gated by exact-string match against six hardcoded model IDs, every Anthropic one of which is retired. Also covered on the setup page |
On that fifth row, one first-party detail that is specific to this endpoint rather than general advice. Kunavo's dispatcher drops temperature, top_p and top_k before forwarding, for the catalog models that declare those parameters unsupported — currently Claude Fable 5.1, Claude Fable 5, Claude Opus 5, Claude Opus 4.8, Claude Opus 4.7, Claude Sonnet 5 — and it does so at the protocol switch, so the stripped body is what any retry attempt sees too. For every other model the field is forwarded as OpenManus sent it. That removes one specific 400 for those models; it is not a claim that OpenManus has been tested here. Kunavo has not runtime-tested OpenManus, and nothing on this page is a compatibility result.
If you are weighing routes rather than debugging one, OpenAI-compatible API covers what the generic path does and does not carry, LLM gateway covers when one key across families is worth it, and AI cost optimization covers the difference between the cheapest listed rate and the cheapest way to finish a task — which is the distinction that decides an agent loop. For the same class of diagnosis on another client, see OpenCode provider not found.
Setting OpenManus up rather than repairing it? The endpoint side is three fields in [llm]: model, base_url and api_key. Start at the quickstart, check the request shape against chat completions, and create a Kunavo account when you are ready to fund a key. Keep a working route available while you try it, and run one bounded task before changing anything else.
FAQ
What is the OpenManus token limit?
By default there is none. OpenManus's own ceiling is the max_input_tokens field, which app/config.py declares as Optional with a default of None described as "unlimited", and which appears in no shipped config example — so a stock install never raises its own token-limit error, and any limit you hit comes from the provider instead. When you do set it, LLM.check_token_limit() compares self.total_input_tokens + input_tokens against it, which makes it a cumulative input budget for the entire run rather than a per-request context check. It is unrelated to the model's context window, and unrelated to max_tokens, which caps one response and ships as 8192 in config/config.example.toml. All three were read on branch main on September 21, 2026.
Why does OpenManus hang before reporting the token limit?
Because the limit error is retried, despite a comment saying it is not. All three @retry decorators in app/llm.py — on ask, ask_with_images and ask_tool — are written as retry_if_exception_type((OpenAIError, Exception, ValueError)) with the trailing comment "# Don't retry TokenLimitExceeded". TokenLimitExceeded subclasses OpenManusError, which subclasses Exception, so the bare Exception entry matches it and tenacity retries up to stop_after_attempt(6) with wait_random_exponential(min=1, max=60) backoff. The agent's own handler confirms the shape: app/agent/toolcall.py checks isinstance(e.__cause__, TokenLimitExceeded), which is how a tenacity RetryError arrives, and only then prints "Maximum token limit reached, cannot continue execution". A fix exists but is not merged: PR #1348 was closed unmerged on August 10, 2026 and its resubmission #1407 was still open and unmerged on September 21, 2026. This is read from the source, not reproduced by running it.
How do I fix Error: Unknown tool 'BrowserUseTool' in OpenManus?
Update your checkout, because on current OpenManus main that class does not exist. The local browser tool was removed on August 15, 2026 in commits ab8dfe43 and 05c5bbb1; app/tool/ contains no browser_use_tool.py, and the only occurrence of the string BrowserUseTool anywhere in the tree is a commented-out line in app/agent/sandbox_agent.py. On the default Manus agent that main.py builds, browser work is now an out-of-process MCP server started as uvx browser-use --cli-mcp, exposing tools named browser_exec and browser_screenshot; the separate Daytona-sandbox entry point sandbox_main.py still registers a local browser tool of its own, named sandbox_browser. On the March 2025 code the reporter of issue #789 was running, the cause was the model emitting the Python class name instead of the registered tool name — their own log shows the very next step dispatching cleanly when it called browser_use instead, and their closing line reads "BrowserUseTool seems not work, but browser_use can". The string itself is generic: app/agent/toolcall.py returns f"Error: Unknown tool '{name}'" for any name missing from available_tools.tool_map, so the same message appears today for any tool the model invents.
Is issue #789 fixed, and what OpenManus version has the fix?
It is not fixed and there is no version to cite. Issue #789, "Result: Error: Unknown tool 'BrowserUseTool'", was opened on March 18, 2025 and was still open on September 21, 2026, labelled inactive, with three comments — one suggesting a stronger model, the reporter agreeing to try one, and an inactivity bot. The related token-limit report, issue #779 "hitting token limit", was closed on September 17, 2026 by that same inactivity bot with state_reason not_planned, which is a timeout rather than a fix. And OpenManus has no current release to name: its only three tags, v0.1.0, v0.2.0 and v0.3.0, were all published within 34 seconds of each other on April 10, 2025, and nothing has been tagged since, so everyone runs untagged main. Cite a commit date, not a version number.
Will switching API provider fix an OpenManus token or tool error?
No, and both failure modes are worth separating from the ones that genuinely are provider-shaped. The token-limit message named above is produced by OpenManus's own accounting against your own configured ceiling before any request is sent, so no endpoint can change it. The Unknown tool message is produced by OpenManus's tool dispatch when the model names something unregistered, which is a tool-calling-fidelity property of the model, and the only advice ever given on issue #789 was to try a different model for exactly that reason. What a different endpoint does change: a provider-side context-length rejection arrives as an OpenAIError rather than TokenLimitExceeded; a fresh copy of the shipped example config fails with a model error rather than a token error, because it still names a Claude ID that Anthropic retired on February 19, 2026; and OpenManus always sends a temperature outside its two hardcoded reasoning IDs, which is a 400-shaped failure on models whose vendor has deprecated that parameter.
Does OpenManus count tokens the same way my provider does?
No. OpenManus counts locally with tiktoken, and LLM.__init__ calls tiktoken.encoding_for_model(self.model) inside a try that falls back to cl100k_base on KeyError. For a Claude or Gemini ID, or any gateway-namespaced ID that tiktoken has no preset for, the budget OpenManus enforces is a cl100k_base estimate rather than the provider's count, and its TokenCounter adds fixed constants of its own — 4 tokens per message, 2 formatting tokens, 85 for a low-detail image and 170 per high-detail tile. Reconcile against the usage your provider account recorded, not against OpenManus's logged totals. Checked on branch main, September 21, 2026, with tiktoken~=0.9.0 pinned in requirements.txt.
Checked September 21, 2026 and not more widely: app/llm.py, app/config.py, app/agent/toolcall.py, app/agent/manus.py, app/agent/base.py, app/agent/sandbox_agent.py, app/tool/sandbox/sb_browser_tool.py, sandbox_main.py, app/exceptions.py, requirements.txt, config/config.example.toml and the README on branch main; a directory listing of app/tool/; the commit history of the deleted browser tool; the GitHub records for issues #779 and #789, their comments, and pull requests #1348, #1391 and #1407; the repository and release metadata; and Anthropic's model-deprecation page. Nothing was executed — no install, no OpenManus run, no reproduction of either error, and no request through OpenManus at any endpoint — so every behavioural claim here is a source read rather than an observed failure, and no successful minimal run is reported because none was performed. Kunavo token rates come from the live catalog, and every dollar figure is illustrative token arithmetic rather than a measured task cost.