From 7fdbbfe1711618755fe5361133e8fdac3725264e Mon Sep 17 00:00:00 2001 From: rachit367 Date: Tue, 23 Jun 2026 16:25:24 +0530 Subject: [PATCH 1/2] fix(web): return graceful error for unknown search context context: resolves a named search context. When the context did not exist, onExpandSearchContext threw a plain Error, which is not caught by the SyntaxError-only handler and crashed the request. Throw a ServiceErrorException with SEARCH_CONTEXT_NOT_FOUND so it returns a clean 404 instead. Fixes #1312 --- .../web/src/features/search/parser.test.ts | 45 +++++++++++++++++++ packages/web/src/features/search/parser.ts | 6 ++- 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 packages/web/src/features/search/parser.test.ts diff --git a/packages/web/src/features/search/parser.test.ts b/packages/web/src/features/search/parser.test.ts new file mode 100644 index 000000000..69c4fcb47 --- /dev/null +++ b/packages/web/src/features/search/parser.test.ts @@ -0,0 +1,45 @@ +import { describe, expect, it } from 'vitest'; +import type { PrismaClient } from '@sourcebot/db'; +import { parseQuerySyntaxIntoIR } from './parser'; +import { ServiceErrorException } from '@/lib/serviceError'; +import { ErrorCode } from '@/lib/errorCodes'; + +describe('parseQuerySyntaxIntoIR', () => { + it('throws a ServiceErrorException when a search context is not found', async () => { + const prisma = { + searchContext: { + findUnique: async () => null, + }, + } as unknown as PrismaClient; + + const promise = parseQuerySyntaxIntoIR({ + query: 'Helpers context:0', + options: {}, + prisma, + }); + + await expect(promise).rejects.toBeInstanceOf(ServiceErrorException); + await expect(promise).rejects.toMatchObject({ + serviceError: { errorCode: ErrorCode.SEARCH_CONTEXT_NOT_FOUND }, + }); + }); + + it('expands a search context into its repo set when found', async () => { + const prisma = { + searchContext: { + findUnique: async () => ({ + repos: [{ name: 'org/repo-a' }, { name: 'org/repo-b' }], + }), + }, + } as unknown as PrismaClient; + + const ir = await parseQuerySyntaxIntoIR({ + query: 'context:my-context', + options: {}, + prisma, + }); + + expect(JSON.stringify(ir)).toContain('org/repo-a'); + expect(JSON.stringify(ir)).toContain('org/repo-b'); + }); +}); diff --git a/packages/web/src/features/search/parser.ts b/packages/web/src/features/search/parser.ts index 3b188a825..bb3ee5d77 100644 --- a/packages/web/src/features/search/parser.ts +++ b/packages/web/src/features/search/parser.ts @@ -114,7 +114,11 @@ export const parseQuerySyntaxIntoIR = async ({ }); if (!context) { - throw new Error(`Search context "${contextName}" not found`); + throw new ServiceErrorException({ + statusCode: StatusCodes.NOT_FOUND, + errorCode: ErrorCode.SEARCH_CONTEXT_NOT_FOUND, + message: `Search context "${contextName}" not found`, + }); } return context.repos.map((repo) => repo.name); From 2f09e687bcc65566f3d7ec205711a651a7c4fb67 Mon Sep 17 00:00:00 2001 From: rachit367 Date: Tue, 23 Jun 2026 16:26:19 +0530 Subject: [PATCH 2/2] docs: add changelog entry for search context crash fix --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 593e735db..c11cbafcd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Added per-step token cost tracking and estimated tool call token usage to Ask Sourcebot chat history. [#1353](https://github.com/sourcebot-dev/sourcebot/pull/1353) +### Fixed +- Fixed a crash when searching with `context:` referencing a search context that does not exist; it now returns a graceful error. [#1362](https://github.com/sourcebot-dev/sourcebot/pull/1362) + ## [5.0.4] - 2026-06-18 ### Changed