Skip to content

Tool-calling errors are swallowed and never surface in useLLM().error #1157

@msluszniak

Description

@msluszniak

Description

When useLLM is configured with toolsConfig, any error that happens on the tool-execution path is silently dropped. The error reaches neither llm.error nor the await llm.sendMessage(...) try/catch, so apps that wire an ErrorBanner to those signals show nothing while the JS console reports an unhandled rejection (or a Logger.error).

Where it happens

Two swallowing points in the controller:

  1. parseToolCall catches every parse failure and returns []:
    https://github.com/software-mansion/react-native-executorch/blob/main/packages/react-native-executorch/src/utils/llm.ts#L42-L45

    } catch (e) {
      Logger.error(e);
      return [];
    }
  2. LLMController.sendMessage invokes executeToolCallback fire-and-forget — no .catch, not awaited:
    https://github.com/software-mansion/react-native-executorch/blob/main/packages/react-native-executorch/src/controllers/LLMController.ts#L427-L441

    if (this.toolsConfig) {
      const toolCalls = parseToolCall(response);
      for (const toolCall of toolCalls) {
        this.toolsConfig
          .executeToolCallback(toolCall)
          .then((toolResponse: string | null) => { ... });
      }
    }

Reproduction

  1. Open the llm demo app → Tool calling screen.
  2. Switch the picker to a non-tool-trained model (e.g. Llama 3.2 1B QLoRA).
  3. Send a tool-shaped prompt (What events do I have today?).
  4. JS logs an error from parseToolCall (or an unhandled rejection if the callback throws), but the on-screen ErrorBanner stays empty.

Expected

Tool-side errors should propagate so apps can display them. Concretely:

  • LLMController.sendMessage should await the tool callbacks under try/catch and forward any failure into the existing error path the hook already exposes as error.
  • parseToolCall parse failures are a softer case — empty result is sometimes correct (model legitimately decided not to call a tool). At minimum, distinguish "no tool call in output" from "malformed tool-call JSON" and surface the latter (e.g. via a typed warning or an error channel).

Notes

Metadata

Metadata

Assignees

No one assigned

    Labels

    user expThis issue tackles problems with user experience e.g. overcomplicated API

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions