OpenClaw: Unsupported Custom Tool Call (execexec) Fix

unsupported custom tool call: execexec means the tool registry holds no tool by that name. Why the name is not yours, and the three ways a tool goes missing.

OpenClaw: Unsupported Custom Tool Call (execexec) Fix

TL;DR: unsupported custom tool call: execexec is the tool registry refusing a name it does not hold. The name after the colon comes from the call, not from your config, so searching your config for execexec will usually find nothing. Check what is actually registered rather than what you think you registered: a tool is absent either because nothing registered it, because it was skipped as a duplicate of a name already taken, or because it was skipped for using a reserved name. All three are decided when the registry is built, which is why restarting changes nothing.

unsupported custom tool call: execexec is one of the more confusing OpenClaw failures to land in a log, because the name in the message is one you have never typed and cannot find anywhere in your setup.


Contents


What “unsupported custom tool call” Is Actually Reporting

The error comes from the tool registry, the component that holds the set of tools a model is allowed to invoke and dispatches a call to the right handler. When a call arrives, the registry looks the name up. If the name is present, the call goes to that handler. If it is not, the registry has nothing to dispatch to and says so.

That is the whole of it, and it is worth being precise about what it rules out. No tool ran. No handler threw. No sandbox refused anything. The failure happened before any of that, in a lookup, which means the interesting question is not what the tool did but why the registry does not have it.

This also tells you the error is not about the arguments. A malformed argument object produces a different complaint entirely, about parsing or about a payload shape. If the registry never found the tool, it never looked at what you were asking the tool to do.

Why execexec Is Not a String You Wrote

The text after the colon is echoed from the incoming call. It is the name the model asked for, reproduced exactly, and it is not read back from your configuration. So the first instinct, to grep the config for execexec, is reasonable and will usually come back empty. That empty result is not a sign that something is corrupt. It is the expected result.

A doubled prefix is the tell. execexec reads as exec with exec in front of it, which is the shape a name takes when it has been assembled from two pieces that both carry the prefix: a namespace joined to a name that already included it, or a fragment concatenated onto a name during streaming. The registry has no opinion about any of this. It received a name, the name was not in the set, and it declined.

What that means practically is that the useful comparison is between the name in the error and the names the registry actually holds. If a tool you expect is registered as exec and the call asks for execexec, you are looking at a naming mismatch on the way in. If nothing resembling exec is registered at all, you are looking at a tool that never made it into the registry, and the doubled name is a second problem sitting on top of the first.

Custom Tool Call or Plain Call: Two Messages, One Registry

The same registry raises two closely related messages, and they are not interchangeable.

unsupported custom tool call: <name> is the custom tool path. Custom tools take freeform input rather than a structured argument object, and they are dispatched by name on their own branch.

unsupported call: <name> is the function tool path, where the model supplies a JSON object of arguments against a declared schema.

Both mean the name was not found. Which one you get tells you which shape the model used to make the call, and that is a genuinely useful narrowing step, because a tool is registered for one shape or the other. A tool declared as a function tool and invoked as a custom tool will not be found on the custom path even though it is, in an ordinary sense, registered. The registry is not being pedantic here. The two paths have different dispatch and different argument handling, and a name in one is not a name in the other.

So before assuming a tool is missing, check which message you have. “Registered, but on the other path” looks identical in a log to “not registered at all”, and only one of them is fixed by registering the tool again.

The Three Ways a Tool Goes Missing

A tool is absent from the registry for one of three reasons, and they are worth separating because two of them are silent.

Nothing registered it. The plugin or extension that supplies the tool did not load, or loaded and did not register. This is the case people expect, and it is usually the case with a visible cause somewhere earlier in the log.

It was skipped as a duplicate. When an external tool is added under a name that is already registered, the registry skips the incoming one rather than replacing what is there or failing loudly. The name stays bound to whatever claimed it first. If two sources supply a tool with the same name, one of them wins silently and the other is gone, and which one wins depends on registration order rather than on anything you configured.

It was skipped for a reserved name. The registry keeps a set of names it will not let external tools take, and an external tool asking for one of them is skipped on the same quiet terms. From outside, a tool skipped for a reserved name and a tool that never loaded look the same.

The second and third are the ones that cost time. Both are skips rather than errors, so the agent starts cleanly, reports nothing unusual, and behaves normally until the first call to the tool that was dropped. The gap between the start and the symptom can be long, which is why the failure so often looks like it appeared out of nowhere.

How to Tell Which One You Have

Work from what is registered, not from what you intended to register.

Start by listing the tools the agent is actually exposing for the session that failed, and compare that list against the name in the error. This single comparison separates the whole problem into two halves. If a similar name is present, you have a naming mismatch and the fix is on the call side. If nothing similar is present, the tool is genuinely absent and the fix is on the registration side.

If the tool is absent, read the startup output for the registration pass rather than for errors. A duplicate skip and a reserved-name skip are recorded there, and they are recorded at a level that is easy to scroll past because nothing about them looks like a failure. Searching that output for the tool’s name is more reliable than searching it for the word error, because the message you want does not contain it.

If the same tool name is supplied by more than one source, that is the answer on its own. Two sources, one name, and the registry keeps the first. Rename one of them and the collision goes away.

If the tool is present under a name close to the one in the error, look at how the call is being built rather than at the tool. A namespace prefix applied twice, or applied to a name that already carried it, produces exactly the doubled string in the message.

Why Restarting Does Not Help

The registry is built once, from whatever the agent has loaded, and the decisions about what is in it are made then. A duplicate is skipped during that build. A reserved name is skipped during that build. A plugin that failed to load contributed nothing during that build. A call that arrives later is matched against the result.

Restarting runs the same build from the same inputs and produces the same registry, so the same call fails the same way. It is a reasonable thing to try once, and it is not a fix, and the reason it is not a fix is the useful part: it tells you the problem is upstream of the call, in what the registry was given, rather than in the state the process has drifted into.

That is also why this error is stable rather than intermittent. An intermittent failure on this message would mean the registry is being built differently between runs, which points at load order or at a source that is not always available, and that is a different investigation from the one above.


If your error names a tool that should exist and the message reads differently, tool 'read' does not exists is the neighbouring case: there the tool is registered and something filters it out, rather than the registry never holding it.

For the broader set of failures in this family, the OpenClaw errors reference covers the ones that come up most, and OpenClaw production gotchas collects the silent ones that only show up under load. If your problem is a tool that runs and then behaves oddly rather than one that cannot be found, start with OpenClaw doctor instead.

Frequently Asked Questions

What does 'unsupported custom tool call' mean in OpenClaw?

It means the tool registry was asked to run a tool whose name it does not hold. The message is raised by the registry at call time, after the model has already produced the call, so it is a name lookup that failed rather than a tool that ran and errored. The text after the colon is the name that was requested, quoted exactly as it arrived.

Is execexec a typo I made somewhere in my config?

Almost never. The string is echoed from the incoming tool call, not read from your config, so it is the name the model asked for rather than a name you wrote. A doubled prefix like execexec is the signature of a name that was assembled from two pieces, which is why grepping your config for it usually returns nothing.

Why does a restart not fix it?

Because the failure is decided at registration time, not at call time. If a tool was dropped when the registry was built, every later call to it fails the same way, and a restart simply rebuilds the registry from the same inputs. The thing to change is what gets registered, not what gets called.

What is the difference between 'unsupported custom tool call' and 'unsupported call'?

They are two messages from the same registry for two different call shapes. Custom tools take freeform text and are dispatched by name on their own path; function tools take a JSON argument object. A missing name on the first path reports unsupported custom tool call, the second reports unsupported call. Which one you see tells you which shape the model used, and that narrows where the name should have been registered.

Can a tool be registered and still be missing?

Yes, and it is the case people miss. The registry skips an external tool whose name duplicates one already registered, and skips one whose name is reserved. Both are skips rather than failures, so the agent starts cleanly and the gap only shows up later, on the first call to the tool that was quietly dropped.

FleetHelp

Stop Googling OpenClaw errors.

Your agents message ours on Telegram. Production-tested OpenClaw fixes. $99/mo.

Try FleetHelp →

About the Author

Kaxo CTO leads AI infrastructure development and autonomous agent deployment for Canadian businesses. Specializes in self-hosted AI security, multi-agent orchestration, and production automation systems. Based in Ontario, Canada.

Written by
Kaxo CTO
Last Updated: September 18, 2026
Back to Insights
FleetHelp online

Your agents break at 3am.
Ours fix them.

Agent-to-agent support for OpenClaw operators. Your bots DM ours, get production-tested answers. $99/mo.

Learn More →