Skip to content

Commit ade50ef

Browse files
committed
Fix list_issues tool schema validation error #7841
1 parent 636b6ba commit ade50ef

5 files changed

Lines changed: 127 additions & 15 deletions

File tree

.github/.sync-metadata.json

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"lastSync": "2025-11-21T12:58:36.740Z",
3-
"releasesLastFetched": "2025-11-21T12:58:36.750Z",
2+
"lastSync": "2025-11-21T13:02:52.974Z",
3+
"releasesLastFetched": "2025-11-21T13:02:52.978Z",
44
"pushFailures": [],
55
"issues": {
66
"3789": {
@@ -6787,11 +6787,18 @@
67876787
"contentHash": "dfe129dcdea080a6a80636853f906a7a30ca83e1ee17a420b473b5ad8d938d8e"
67886788
},
67896789
"7840": {
6790-
"state": "OPEN",
6790+
"state": "CLOSED",
67916791
"path": "/Users/Shared/github/neomjs/neo/.github/ISSUE/issue-7840.md",
6792+
"closedAt": "2025-11-21T13:00:34Z",
6793+
"updatedAt": "2025-11-21T13:00:34Z",
6794+
"contentHash": "4213e43b1e848f61fdba176407fc6cac0f81846e3981413579953386e2fed0bb"
6795+
},
6796+
"7841": {
6797+
"state": "OPEN",
6798+
"path": "/Users/Shared/github/neomjs/neo/.github/ISSUE/issue-7841.md",
67926799
"closedAt": null,
6793-
"updatedAt": "2025-11-21T12:58:27Z",
6794-
"contentHash": "afe24bb425a5a9cec47908d348775cc102550f606f077a1938c10bb7ae2cc107"
6800+
"updatedAt": "2025-11-21T13:02:43Z",
6801+
"contentHash": "2e9a5e1a2effecf96658c92798e77a6e779aba3bc4f12c004ef33ee7da54c6dd"
67956802
}
67966803
},
67976804
"releases": {

.github/ISSUE/issue-7840.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
---
22
id: 7840
33
title: Optimize SessionService.summarizeSessions with Promise.all
4-
state: OPEN
4+
state: CLOSED
55
labels:
66
- enhancement
77
- ai
8-
assignees: []
8+
assignees:
9+
- tobiu
910
createdAt: '2025-11-21T12:58:27Z'
10-
updatedAt: '2025-11-21T12:58:27Z'
11+
updatedAt: '2025-11-21T13:00:34Z'
1112
githubUrl: 'https://github.com/neomjs/neo/issues/7840'
1213
author: tobiu
1314
commentsCount: 0
@@ -17,6 +18,7 @@ subIssuesCompleted: 0
1718
subIssuesTotal: 0
1819
blockedBy: []
1920
blocking: []
21+
closedAt: '2025-11-21T13:00:34Z'
2022
---
2123
# Optimize SessionService.summarizeSessions with Promise.all
2224

@@ -26,4 +28,7 @@ Refactor `SessionService.summarizeSessions` to process unsummarized sessions in
2628

2729
- 2025-11-21 @tobiu added the `enhancement` label
2830
- 2025-11-21 @tobiu added the `ai` label
31+
- 2025-11-21 @tobiu assigned to @tobiu
32+
- 2025-11-21 @tobiu referenced in commit `636b6ba` - "Optimize SessionService.summarizeSessions with Promise.all #7840"
33+
- 2025-11-21 @tobiu closed this issue
2934

.github/ISSUE/issue-7841.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
id: 7841
3+
title: Fix list_issues tool schema validation error
4+
state: OPEN
5+
labels:
6+
- bug
7+
- ai
8+
assignees: []
9+
createdAt: '2025-11-21T13:02:43Z'
10+
updatedAt: '2025-11-21T13:02:43Z'
11+
githubUrl: 'https://github.com/neomjs/neo/issues/7841'
12+
author: tobiu
13+
commentsCount: 0
14+
parentIssue: null
15+
subIssues: []
16+
subIssuesCompleted: 0
17+
subIssuesTotal: 0
18+
blockedBy: []
19+
blocking: []
20+
---
21+
# Fix list_issues tool schema validation error
22+
23+
The `list_issues` tool fails with a schema validation error because the `IssueService.listIssues` method returns raw GraphQL response structures for `labels` and `assignees` (nested under `nodes`), whereas the OpenAPI schema expects flat arrays.
24+
25+
**Error:**
26+
`data/issues/0/labels must be array`
27+
`data/issues/0/assignees must be array`
28+
29+
**Fix:**
30+
Transform the GraphQL response in `IssueService.listIssues` to map `labels.nodes` to `labels` and `assignees.nodes` to `assignees` before returning the data.
31+
32+
## Activity Log
33+
34+
- 2025-11-21 @tobiu added the `bug` label
35+
- 2025-11-21 @tobiu added the `ai` label
36+

ai/mcp/server/github-workflow/services/IssueService.mjs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import logger from '../logger.mjs';
66
import {exec} from 'child_process';
77
import {promisify} from 'util';
88
import {spawn} from 'child_process';
9-
import {GET_ISSUE_AND_LABEL_IDS, GET_ISSUE_PARENT, GET_BLOCKED_BY, FETCH_ISSUES_FOR_SYNC} from './queries/issueQueries.mjs';
9+
import {GET_ISSUE_AND_LABEL_IDS, GET_ISSUE_PARENT, GET_BLOCKED_BY, FETCH_ISSUES_FOR_SYNC, FETCH_ISSUES_LIST} from './queries/issueQueries.mjs';
1010
import {GET_PULL_REQUEST_ID} from './queries/pullRequestQueries.mjs';
1111
import {ADD_LABELS, REMOVE_LABELS, ADD_SUB_ISSUE, REMOVE_SUB_ISSUE, ADD_BLOCKED_BY, REMOVE_BLOCKED_BY, GET_ISSUE_ID, ADD_COMMENT} from './queries/mutations.mjs';
1212

@@ -498,16 +498,12 @@ class IssueService extends Base {
498498
limit,
499499
cursor,
500500
states,
501-
since : null,
502501
maxLabels : aiConfig.issueSync.maxLabelsPerIssue,
503-
maxAssignees : aiConfig.issueSync.maxAssigneesPerIssue,
504-
maxComments : aiConfig.issueSync.maxCommentsPerIssue,
505-
maxSubIssues : aiConfig.issueSync.maxSubIssuesPerIssue,
506-
maxTimelineItems: aiConfig.issueSync.maxTimelineItemsPerIssue
502+
maxAssignees : aiConfig.issueSync.maxAssigneesPerIssue
507503
};
508504

509505
try {
510-
const data = await GraphqlService.query(FETCH_ISSUES_FOR_SYNC, variables);
506+
const data = await GraphqlService.query(FETCH_ISSUES_LIST, variables);
511507
let issues = data.repository.issues.nodes || [];
512508

513509
// client-side label filtering if requested
@@ -527,6 +523,12 @@ class IssueService extends Base {
527523
});
528524
}
529525

526+
// Transform in-place to match OpenAPI schema
527+
for (const issue of issues) {
528+
issue.labels = issue.labels?.nodes || [];
529+
issue.assignees = issue.assignees?.nodes || [];
530+
}
531+
530532
return {
531533
count: issues.length,
532534
issues

ai/mcp/server/github-workflow/services/queries/issueQueries.mjs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,68 @@ export const FETCH_ISSUES_FOR_SYNC = `
219219
}
220220
`;
221221

222+
/**
223+
* Optimized query for listing issues with minimal fields required by the Issue schema.
224+
*
225+
* Variables required:
226+
* - $owner: String!
227+
* - $repo: String!
228+
* - $limit: Int!
229+
* - $cursor: String
230+
* - $states: [IssueState!]
231+
* - $maxLabels: Int!
232+
* - $maxAssignees: Int!
233+
*/
234+
export const FETCH_ISSUES_LIST = `
235+
query FetchIssuesList(
236+
$owner: String!
237+
$repo: String!
238+
$limit: Int!
239+
$cursor: String
240+
$states: [IssueState!]
241+
$maxLabels: Int!
242+
$maxAssignees: Int!
243+
) {
244+
repository(owner: $owner, name: $repo) {
245+
issues(
246+
first: $limit
247+
after: $cursor
248+
states: $states
249+
orderBy: {field: UPDATED_AT, direction: DESC}
250+
) {
251+
pageInfo {
252+
hasNextPage
253+
endCursor
254+
}
255+
nodes {
256+
number
257+
title
258+
body
259+
state
260+
createdAt
261+
url
262+
263+
author {
264+
login
265+
}
266+
267+
labels(first: $maxLabels) {
268+
nodes {
269+
name
270+
}
271+
}
272+
273+
assignees(first: $maxAssignees) {
274+
nodes {
275+
login
276+
}
277+
}
278+
}
279+
}
280+
}
281+
}
282+
`;
283+
222284
/**
223285
* Simplified query for fetching a single issue's details.
224286
* Used for individual updates or debugging.

0 commit comments

Comments
 (0)