From 02d62c417589e6058c09f06d9a495fc9b79a075c Mon Sep 17 00:00:00 2001 From: Etienne <45695613+etiennejouan@users.noreply.github.com> Date: Mon, 29 Jun 2026 11:03:16 +0200 Subject: [PATCH] fix(ai-tools): make navigate_app tool schema a valid object root for direct model binding (#22284) ## Problem Using an AI Agent step in a workflow fails with: > Invalid schema for function 'navigate_app': schema must be a JSON Schema of 'type: "object"', got 'type: "None"'. ## Root cause The `navigate_app` tool declared its `inputSchema` as a top-level `z.discriminatedUnion('type', [...])`. When serialized via `toToolJsonSchema`, a discriminated union produces a **root-level `anyOf`** with no top-level `"type"`: ```json { "anyOf": [ { "type": "object", ... }, ... ] } Review in cubic --- .../tool/tools/navigate-tool/navigate-app-tool.schema.ts | 9 ++++++++- .../tool/tools/navigate-tool/navigate-app-tool.ts | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/twenty-server/src/engine/core-modules/tool/tools/navigate-tool/navigate-app-tool.schema.ts b/packages/twenty-server/src/engine/core-modules/tool/tools/navigate-tool/navigate-app-tool.schema.ts index 3cf69f72b2..4e5a571d55 100644 --- a/packages/twenty-server/src/engine/core-modules/tool/tools/navigate-tool/navigate-app-tool.schema.ts +++ b/packages/twenty-server/src/engine/core-modules/tool/tools/navigate-tool/navigate-app-tool.schema.ts @@ -1,6 +1,6 @@ import { z } from 'zod'; -export const NavigateAppInputZodSchema = z.discriminatedUnion('type', [ +export const NavigateAppActionZodSchema = z.discriminatedUnion('type', [ z.object({ type: z .literal('navigateToView') @@ -59,4 +59,11 @@ export const NavigateAppInputZodSchema = z.discriminatedUnion('type', [ }), ]); +export const NavigateAppInputZodSchema = z.object({ + navigation: NavigateAppActionZodSchema.describe( + 'The navigation action to perform.', + ), +}); + +export type NavigateAppAction = z.infer; export type NavigateAppInput = z.infer; diff --git a/packages/twenty-server/src/engine/core-modules/tool/tools/navigate-tool/navigate-app-tool.ts b/packages/twenty-server/src/engine/core-modules/tool/tools/navigate-tool/navigate-app-tool.ts index c55e44c269..de45a972f7 100644 --- a/packages/twenty-server/src/engine/core-modules/tool/tools/navigate-tool/navigate-app-tool.ts +++ b/packages/twenty-server/src/engine/core-modules/tool/tools/navigate-tool/navigate-app-tool.ts @@ -54,7 +54,7 @@ export class NavigateAppTool implements Tool { }; } - const input: NavigateAppInput = parseResult.data; + const input: NavigateAppInput['navigation'] = parseResult.data.navigation; switch (input.type) { case 'navigateToView':