Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/lib/agents/search/researcher/actions/academicSearch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const academicSearchAction: ResearchAction<typeof schema> = {
config.classification.classification.skipSearch === false &&
config.classification.classification.academicSearch === true,
execute: async (input, additionalConfig) => {
input.queries = input.queries.slice(0, 3);
const queries = (input.queries ?? []).slice(0, 3);

const researchBlock = additionalConfig.session.getBlock(
additionalConfig.researchBlockId,
Expand All @@ -40,7 +40,7 @@ const academicSearchAction: ResearchAction<typeof schema> = {
researchBlock.data.subSteps.push({
type: 'searching',
id: crypto.randomUUID(),
searching: input.queries,
searching: queries,
});

additionalConfig.session.updateBlock(additionalConfig.researchBlockId, [
Expand All @@ -62,7 +62,7 @@ const academicSearchAction: ResearchAction<typeof schema> = {
engines: ['arxiv', 'google scholar', 'pubmed'],
});

const resultChunks: Chunk[] = res.results.map((r) => ({
const resultChunks: Chunk[] = (res.results ?? []).map((r) => ({
content: r.content || r.title,
metadata: {
title: r.title,
Expand Down Expand Up @@ -117,7 +117,7 @@ const academicSearchAction: ResearchAction<typeof schema> = {
}
};

await Promise.all(input.queries.map(search));
await Promise.all(queries.map(search));

return {
type: 'search_results',
Expand Down
4 changes: 2 additions & 2 deletions src/lib/agents/search/researcher/actions/scrapeURL.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const scrapeURLAction: ResearchAction<typeof schema> = {
getDescription: () => actionDescription,
enabled: (_) => true,
execute: async (params, additionalConfig) => {
params.urls = params.urls.slice(0, 3);
const urls = (params.urls ?? []).slice(0, 3);

let readingBlockId = crypto.randomUUID();
let readingEmitted = false;
Expand All @@ -37,7 +37,7 @@ const scrapeURLAction: ResearchAction<typeof schema> = {
const results: Chunk[] = [];

await Promise.all(
params.urls.map(async (url) => {
urls.map(async (url) => {
try {
const res = await fetch(url);
const text = await res.text();
Expand Down
8 changes: 4 additions & 4 deletions src/lib/agents/search/researcher/actions/socialSearch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const socialSearchAction: ResearchAction<typeof schema> = {
config.classification.classification.skipSearch === false &&
config.classification.classification.discussionSearch === true,
execute: async (input, additionalConfig) => {
input.queries = input.queries.slice(0, 3);
const queries = (input.queries ?? []).slice(0, 3);

const researchBlock = additionalConfig.session.getBlock(
additionalConfig.researchBlockId,
Expand All @@ -40,7 +40,7 @@ const socialSearchAction: ResearchAction<typeof schema> = {
researchBlock.data.subSteps.push({
type: 'searching',
id: crypto.randomUUID(),
searching: input.queries,
searching: queries,
});

additionalConfig.session.updateBlock(additionalConfig.researchBlockId, [
Expand All @@ -62,7 +62,7 @@ const socialSearchAction: ResearchAction<typeof schema> = {
engines: ['reddit'],
});

const resultChunks: Chunk[] = res.results.map((r) => ({
const resultChunks: Chunk[] = (res.results ?? []).map((r) => ({
content: r.content || r.title,
metadata: {
title: r.title,
Expand Down Expand Up @@ -117,7 +117,7 @@ const socialSearchAction: ResearchAction<typeof schema> = {
}
};

await Promise.all(input.queries.map(search));
await Promise.all(queries.map(search));

return {
type: 'search_results',
Expand Down
6 changes: 3 additions & 3 deletions src/lib/agents/search/researcher/actions/uploadsSearch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const uploadsSearchAction: ResearchAction<typeof schema> = {
Never use this tool to search the web or for information that is not contained within the user's uploaded files.
`,
execute: async (input, additionalConfig) => {
input.queries = input.queries.slice(0, 3);
const queries = (input.queries ?? []).slice(0, 3);

const researchBlock = additionalConfig.session.getBlock(
additionalConfig.researchBlockId,
Expand All @@ -37,7 +37,7 @@ const uploadsSearchAction: ResearchAction<typeof schema> = {
researchBlock.data.subSteps.push({
id: crypto.randomUUID(),
type: 'upload_searching',
queries: input.queries,
queries: queries,
});

additionalConfig.session.updateBlock(additionalConfig.researchBlockId, [
Expand All @@ -54,7 +54,7 @@ const uploadsSearchAction: ResearchAction<typeof schema> = {
fileIds: additionalConfig.fileIds,
});

const results = await uploadStore.query(input.queries, 10);
const results = await uploadStore.query(queries, 10);

const seenIds = new Map<string, number>();

Expand Down
8 changes: 4 additions & 4 deletions src/lib/agents/search/researcher/actions/webSearch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ const webSearchAction: ResearchAction<typeof actionSchema> = {
config.sources.includes('web') &&
config.classification.classification.skipSearch === false,
execute: async (input, additionalConfig) => {
input.queries = input.queries.slice(0, 3);
const queries = (input.queries ?? []).slice(0, 3);
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Mar 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: ?? [] only guards null/undefined; non-array input.queries can still break .map() and crash action execution.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/lib/agents/search/researcher/actions/webSearch.ts, line 88:

<comment>`?? []` only guards null/undefined; non-array `input.queries` can still break `.map()` and crash action execution.</comment>

<file context>
@@ -85,7 +85,7 @@ const webSearchAction: ResearchAction<typeof actionSchema> = {
     config.classification.classification.skipSearch === false,
   execute: async (input, additionalConfig) => {
-    input.queries = input.queries.slice(0, 3);
+    const queries = (input.queries ?? []).slice(0, 3);
 
     const researchBlock = additionalConfig.session.getBlock(
</file context>
Fix with Cubic


const researchBlock = additionalConfig.session.getBlock(
additionalConfig.researchBlockId,
Expand All @@ -95,7 +95,7 @@ const webSearchAction: ResearchAction<typeof actionSchema> = {
researchBlock.data.subSteps.push({
id: crypto.randomUUID(),
type: 'searching',
searching: input.queries,
searching: queries,
});

additionalConfig.session.updateBlock(additionalConfig.researchBlockId, [
Expand All @@ -115,7 +115,7 @@ const webSearchAction: ResearchAction<typeof actionSchema> = {
const search = async (q: string) => {
const res = await searchSearxng(q);

const resultChunks: Chunk[] = res.results.map((r) => ({
const resultChunks: Chunk[] = (res.results ?? []).map((r) => ({
content: r.content || r.title,
metadata: {
title: r.title,
Expand Down Expand Up @@ -170,7 +170,7 @@ const webSearchAction: ResearchAction<typeof actionSchema> = {
}
};

await Promise.all(input.queries.map(search));
await Promise.all(queries.map(search));

return {
type: 'search_results',
Expand Down
4 changes: 2 additions & 2 deletions src/lib/searxng.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ export const searchSearxng = async (
const res = await fetch(url);
const data = await res.json();

const results: SearxngSearchResult[] = data.results;
const suggestions: string[] = data.suggestions;
const results: SearxngSearchResult[] = data.results ?? [];
const suggestions: string[] = data.suggestions ?? [];

return { results, suggestions };
};