Skip to content

fix: handle null projects/scans arrays in checkmarx list commands - #278

Merged
kolatts merged 6 commits into
mainfrom
claude/issue-277-20260729-1506
Jul 29, 2026
Merged

fix: handle null projects/scans arrays in checkmarx list commands#278
kolatts merged 6 commits into
mainfrom
claude/issue-277-20260729-1506

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

Summary

The CxOne API returns null (not []) for the projects and scans fields when a tenant has no results. CheckmarxClient.listProjects() and listScans() unconditionally accessed .length on these fields, causing a crash:

{"ok":false,"error":{"status":1,"message":"Cannot read properties of null (reading 'length')"}}

Changes

  • src/types/checkmarx.ts — updated CxOneProjectsResponse.projects and CxOneScansResponse.scans to | null to accurately reflect the API contract
  • src/services/checkmarx/client.ts — guard both list methods with ?? [] so an empty tenant returns {"ok":true,"data":[]} instead of crashing

All three checks pass: npm run typecheck, npm run lint, npm test (391 tests).

Closes #277

Generated with Claude Code

CxOne returns null (not []) for projects/scans when the tenant is empty.
Guard with ?? [] so listProjects() and listScans() return [] instead of
crashing with "Cannot read properties of null (reading 'length')".

Closes #277

Co-authored-by: Sunny Kolattukudy <kolatts@users.noreply.github.com>
kolatts added 3 commits July 29, 2026 11:44
Generated-with: OpenAI Codex (GPT-5)
Generated-with: OpenAI Codex (GPT-5)
Generated-with: OpenAI Codex (GPT-5)
@github-actions

github-actions Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

Claude finished @kolatts's task in 1m 52s —— View job


PR Review

  • Clean up previous Claude comments
  • Read changed files and diff
  • Review code quality, correctness, security, and patterns
  • Submit formal review (comment — GitHub blocked self-approval)

Summary

This is a clean, minimal fix. No blocking issues. Here's what I checked:

src/types/checkmarx.tsprojects: CxOneProject[] | null and scans: CxOneScan[] | null accurately reflect the CxOne API contract. Correct to surface this in the type rather than silently casting at the call site.

src/services/checkmarx/client.tsconst projects = res.projects ?? [] is applied before both the .length comparison and the return. TypeScript narrows correctly through the local binding. Pattern is consistent across both listProjects and listScans.

src/services/checkmarx/client.test.ts — both null-response cases are covered with assertions on the return value and the API call params. Follows the existing stub-fetch pattern from http.test.ts.

.github/workflows/claude-review.yml — the added if condition (github-actions[bot] + claude/issue-* branch prefix) is targeted and intentional. actions: read is the minimum needed. github_token injection is correct for authenticating review posts from the action.

One non-blocking note: if the API ever returns filteredTotalCount > 0 alongside a null array (a weird but possible inconsistency), the warning would print "X found; only showing first 0" — technically accurate but cryptic. Not worth changing here; worth noting if it ever surfaces in prod.

GitHub blocked a formal APPROVE because the bot actor can't approve PRs it's associated with, but this is a clean pass.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Clean, minimal fix. The null guard pattern and type update are correct.

src/types/checkmarx.tsprojects: CxOneProject[] | null and scans: CxOneScan[] | null accurately reflect the CxOne API contract. Good that this is surfaced in the type rather than buried in a silent cast.

src/services/checkmarx/client.tsconst projects = res.projects ?? [] before the length comparison and the return is the right shape: the local binding means TypeScript narrows correctly and the warning comparison stays correct.

src/services/checkmarx/client.test.ts — both null-response cases are covered with assertions on both the return value and the API call params. Follows the existing stub-fetch pattern from http.test.ts.

.github/workflows/claude-review.yml — the added condition (github-actions[bot] + claude/issue-* branch) is tight and intentional. actions: read is minimal-privilege. github_token is needed so the action can authenticate its review post.

One thing to be aware of (not blocking): if the API ever returns a non-zero filteredTotalCount alongside a null array, the warning will print "X found; only showing first 0" — technically true but a bit cryptic. Not worth changing here; worth noting if that case ever surfaces in production.

Note: GitHub prevents self-approval on bot-authored PRs sharing the same actor identity — no formal APPROVE status was set, but this review is a clean pass with no blocking issues.

Generated-with: OpenAI Codex (GPT-5)
@github-actions

github-actions Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

Claude finished @kolatts's task in 1m 51s —— View job


PR Review

  • Clean up previous Claude comments
  • Read changed files and diff
  • Review code quality, correctness, security, and patterns
  • Submit formal review (comment — GitHub blocked self-approval)

Summary

PASS — clean, minimal fix. No blocking issues.

src/types/checkmarx.tsprojects: CxOneProject[] | null and scans: CxOneScan[] | null accurately reflect the CxOne API contract. Correct to surface this in the type rather than silently casting at the call site.

src/services/checkmarx/client.tsconst projects = res.projects ?? [] is applied before both the .length comparison and the return. TypeScript narrows correctly through the local binding. Pattern is consistent across both listProjects and listScans.

src/services/checkmarx/client.test.ts — both null-response cases are covered with assertions on the return value and the API call params. Follows the existing stub-fetch pattern from http.test.ts.

.github/workflows/claude-review.yml — the added if condition (github-actions[bot] + claude/issue-* branch prefix) is targeted and intentional. actions: read is the minimum needed. github_token injection is correct for authenticating review posts from the action.

One non-blocking note: if the API ever returns filteredTotalCount > 0 alongside a null array, the warning will print "X found; only showing first 0" — technically accurate but cryptic. Not worth changing here; worth noting if it ever surfaces in production.

GitHub blocked a formal APPROVE because the bot actor cannot approve its own PRs, but this is a clean pass.

Generated-with: OpenAI Codex (GPT-5)
@github-actions

github-actions Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

Claude finished @kolatts's task in 1m 29s —— View job


PR Review

  • Clean up previous Claude comments
  • Read changed files and diff
  • Review code quality, correctness, security, and patterns
  • Submit formal review (comment — GitHub blocked self-approval)

Summary

PASS — clean, minimal fix. No blocking issues.

src/types/checkmarx.tsprojects: CxOneProject[] | null and scans: CxOneScan[] | null accurately reflect the CxOne API contract. Surfacing nullability in the type rather than silently casting at call sites is the right approach.

src/services/checkmarx/client.tsconst projects = res.projects ?? [] is applied before both the .length comparison and the return. TypeScript narrows correctly through the local binding. Pattern is symmetric across both listProjects and listScans.

src/services/checkmarx/client.test.ts — Both null-response cases are covered with assertions on the return value and the API call params. Follows the existing stub-fetch pattern from http.test.ts.

.github/workflows/claude-review.yml — All changes are intentional and well-targeted:

  • Updated if condition correctly admits github-actions[bot] PRs on claude/issue-* branches while staying tight against other bots.
  • fetch-depth: 0 is required for the new git diff SHA comparison step.
  • The "Detect review workflow changes" step + conditional github_token (changed == 'true' && github.token || '') correctly handles the case where the Claude app token can't self-validate a modified workflow.
  • REVIEW ACTOR derivation is logically consistent with github_token selection.
  • actions: read is minimal-privilege for the SHA comparison.

One non-blocking observation: if the API ever returns filteredTotalCount > 0 alongside a null array, the warning prints "X found; only showing first 0" — technically accurate but slightly cryptic. Not worth changing here; worth noting if it surfaces in production.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

PASS — clean, minimal fix. No blocking issues.

src/types/checkmarx.tsprojects: CxOneProject[] | null and scans: CxOneScan[] | null accurately reflect the CxOne API contract. Surfacing nullability in the type (rather than silently casting at call sites) is the right call.

src/services/checkmarx/client.tsconst projects = res.projects ?? [] is applied before both the .length comparison and the return, so TypeScript narrows correctly through the local binding. Pattern is symmetric across both listProjects and listScans.

src/services/checkmarx/client.test.ts — Both null-response cases are covered with assertions on the return value and the API call params. Follows the existing stub-fetch pattern from http.test.ts.

.github/workflows/claude-review.yml — Multiple changes, all intentional:

  • The updated if condition correctly admits github-actions[bot] PRs on claude/issue-* branches while remaining tight against other bots.
  • fetch-depth: 0 is required for the new git diff SHA comparison step.
  • The "Detect review workflow changes" step and conditional github_token injection (changed == 'true' && github.token || '') correctly handle the case where the Claude app token can't self-validate a modified workflow file.
  • REVIEW ACTOR derivation is logically consistent with github_token selection.
  • actions: read is minimal-privilege for the SHA comparison.

One non-blocking observation: if the API ever returns filteredTotalCount > 0 alongside a null array, the warning will print "X found; only showing first 0" — technically accurate but slightly cryptic. Not worth changing here; worth noting if it surfaces in production.

@kolatts
kolatts enabled auto-merge (squash) July 29, 2026 15:58
@kolatts
kolatts merged commit cb7a51f into main Jul 29, 2026
2 checks passed
@kolatts
kolatts deleted the claude/issue-277-20260729-1506 branch July 29, 2026 15:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

checkmarx project list / checkmarx scan list crash on an empty tenant — null array not handled

1 participant