diff --git a/dev/src/server/adk_api_server.ts b/dev/src/server/adk_api_server.ts index a52ad63ab..701bb152a 100644 --- a/dev/src/server/adk_api_server.ts +++ b/dev/src/server/adk_api_server.ts @@ -863,11 +863,13 @@ export class AdkApiServer { }); req.on('end', async () => { this.logger.info(`Received Reasoning Engine raw body: ${rawBody}`); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - let body: any = {}; + let body: object = {}; if (rawBody) { try { - body = JSON.parse(rawBody); + const parsed: unknown = JSON.parse(rawBody); + if (typeof parsed === 'object' && parsed !== null) { + body = parsed; + } } catch (e) { this.logger.error(`Failed to parse raw body as JSON: ${e}`); } diff --git a/dev/test/server/adk_api_server_test.ts b/dev/test/server/adk_api_server_test.ts index d6db712d2..b79153a66 100644 --- a/dev/test/server/adk_api_server_test.ts +++ b/dev/test/server/adk_api_server_test.ts @@ -1152,6 +1152,34 @@ describe('AdkWebServer', () => { ); }); + it('should return 400 when the raw body is JSON null', async () => { + const res = await fetch(`${server.url}/api/reasoning_engine`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json,application/json', + }, + body: 'null', + }); + + expect(res.status).toBe(400); + const data = (await res.json()) as {error: string}; + expect(data.error).toContain('appName is required'); + }); + + it('should return 400 when the raw body is a JSON primitive', async () => { + const res = await fetch(`${server.url}/api/reasoning_engine`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json,application/json', + }, + body: '"hello"', + }); + + expect(res.status).toBe(400); + const data = (await res.json()) as {error: string}; + expect(data.error).toContain('appName is required'); + }); + it('should return 400 if appName is missing', async () => { try { await client.post('/api/reasoning_engine', {