Skip to content

[CI Failure Doctor] CI Failure Doctor: close_older_issues.test.cjs uses Jest instead of Vitest #10895

Description

@github-actions

Summary

The CI workflow failed on commit c1c6704 (PR #10882) because the newly added test file close_older_issues.test.cjs uses Jest test framework syntax (@jest/globals and jest.fn()) instead of the Vitest framework used throughout the codebase.

Failure Details

Root Cause Analysis

Primary Error

Error: Cannot find module '@jest/globals'
Require stack:
- /home/runner/work/gh-aw/gh-aw/actions/setup/js/close_older_issues.test.cjs
 ❯ close_older_issues.test.cjs:3:46

Technical Details

The test file close_older_issues.test.cjs (334 lines) uses Jest syntax patterns that are incompatible with Vitest:

Incorrect imports (Line 3):

const { describe, it, expect, beforeEach } = require("@jest/globals");

Incorrect mocking (Lines 8-10):

global.core = {
  info: jest.fn(),    // ❌ Should be vi.fn()
  warning: jest.fn(),
  error: jest.fn(),
};

Incorrect module loading:

  • Uses CommonJS require() instead of ES modules import

Correct Patterns Used in Other Test Files

All existing test files use Vitest:

// ✅ Correct - From add_comment.test.cjs, add_labels.test.cjs, etc.
import { describe, it, expect, beforeEach, vi } from "vitest";

const mockCore = {
  debug: vi.fn(),
  info: vi.fn(),
  warning: vi.fn(),
  error: vi.fn(),
};

Additional Test Failures

The run also showed 42 other test failures, mostly in collect_ndjson_output.test.cjs and safe_outputs_mcp_server_defaults.test.cjs, but these appear to be pre-existing issues unrelated to this specific failure.

Recommended Actions

Fix #1: Convert Test File to Vitest (Required)

Replace Jest syntax with Vitest in close_older_issues.test.cjs:

Changes needed:

  1. Update imports (line 3):

    // Before:
    const { describe, it, expect, beforeEach } = require("@jest/globals");
    
    // After:
    import { describe, it, expect, beforeEach, vi } from "vitest";
  2. Update module imports (line 4):

    // Before:
    const { closeOlderIssues, ... } = require("./close_older_issues.cjs");
    
    // After:
    import { closeOlderIssues, ... } from "./close_older_issues.cjs";
  3. Update mocking (lines 8-10):

    // Before:
    global.core = {
      info: jest.fn(),
      warning: jest.fn(),
      error: jest.fn(),
    };
    
    // After:
    global.core = {
      info: vi.fn(),
      warning: vi.fn(),
      error: vi.fn(),
    };
  4. Update all mock functions (lines 18-28 and throughout):

    // Before:
    mockGithub = {
      rest: {
        search: {
          issuesAndPullRequests: jest.fn(),
        },
        issues: {
          createComment: jest.fn(),
          update: jest.fn(),
        },
      },
    };
    
    // After:
    mockGithub = {
      rest: {
        search: {
          issuesAndPullRequests: vi.fn(),
        },
        issues: {
          createComment: vi.fn(),
          update: vi.fn(),
        },
      },
    };
  5. Update beforeEach (line 17):

    beforeEach(() => {
      vi.clearAllMocks();  // Instead of jest.clearAllMocks()
      // ... rest of setup
    });

Fix #2: Run Local Tests Before Committing

Always run the full test suite locally:

cd actions/setup/js
npm test

This would have caught the error immediately.

Prevention Strategies

1. Add Pre-commit Validation

Update AGENTS.md to emphasize test validation:

### JavaScript Test Requirements

**ALWAYS use Vitest patterns for JavaScript tests:**

1. **Imports**: Use `import { describe, it, expect, vi } from "vitest"`
2. **Mocking**: Use `vi.fn()` instead of `jest.fn()`
3. **Module loading**: Use ES module `import` instead of `require()`
4. **Clear mocks**: Use `vi.clearAllMocks()` instead of `jest.clearAllMocks()`

**Before committing JavaScript files:**
``````bash
cd actions/setup/js
npm ci              # Install dependencies
npm test           # Run all tests (includes typecheck)
npm run lint       # Run linter

Example - Correct test file structure:

import { describe, it, expect, beforeEach, vi } from "vitest";
import { myFunction } from "./my-module.cjs";

const mockCore = {
  info: vi.fn(),
  warning: vi.fn(),
  error: vi.fn(),
};

describe("my-module", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("should do something", () => {
    // Test implementation
  });
});

### 2. Lint Rule for Jest Usage

Consider adding an ESLint rule to prevent Jest imports:

``````json
{
  "rules": {
    "no-restricted-imports": ["error", {
      "patterns": ["*jest*"]
    }]
  }
}

3. Template Test File

Create a template test file in the repository:

# actions/setup/js/TEMPLATE.test.cjs

AI Team Self-Improvement

Instructions to add to AGENTS.md:

### JavaScript Testing with Vitest (NOT Jest)

**CRITICAL**: This project uses **Vitest**, NOT Jest. Never import from `@jest/globals`.

**Correct test file pattern:**
``````javascript
// ✅ CORRECT - Always use this pattern
import { describe, it, expect, beforeEach, vi } from "vitest";
import { functionToTest } from "./module.cjs";

global.core = {
  info: vi.fn(),      // ✅ Use vi.fn()
  warning: vi.fn(),
  error: vi.fn(),
};

describe("module-name", () => {
  beforeEach(() => {
    vi.clearAllMocks();  // ✅ Use vi.clearAllMocks()
  });

  it("test description", async () => {
    // Test implementation
  });
});

Incorrect patterns to avoid:

// ❌ WRONG - Never use Jest
const { describe, it, expect } = require("@jest/globals");  // ❌ Wrong framework
const module = require("./module.cjs");                      // ❌ Use import instead
jest.fn()                                                    // ❌ Use vi.fn()
jest.clearAllMocks()                                         // ❌ Use vi.clearAllMocks()

Pre-commit checklist for JavaScript tests:

  • Import from vitest, NOT @jest/globals
  • Use vi.fn() for mocks, NOT jest.fn()
  • Use ES module import, NOT require()
  • Run npm test locally before committing
  • All tests pass with npm test

## Historical Context

This is a **new type of failure pattern**. While similar test-related issues have occurred before:
- Issue #3772: "Add test coverage for untested JavaScript files" emphasized using Vitest patterns
- Issue #10427: TypeScript type error in handle_agent_failure.cjs (different error type)

This is the **first time** a test file using Jest syntax has been merged to main, indicating that:
1. The pre-commit validation may not catch framework mismatches
2. Code reviewers may not have caught the Jest/Vitest difference
3. Local testing may have been skipped

## Files Affected

- `actions/setup/js/close_older_issues.test.cjs` - New test file with Jest syntax (334 lines)
- `actions/setup/js/close_older_issues.cjs` - New implementation file (259 lines)
- `actions/setup/js/create_issue.cjs` - Modified to integrate close-older-issues (21 changes)

## PR Context

PR #10882 added the "close-older-issues" feature to allow workflows to automatically close older issues when creating a new one. The implementation looks correct, but the test file was written using the wrong test framework.

## Verification Test

After applying the fix:

``````bash
cd actions/setup/js
npm ci
npm test 2>&1 | grep "close_older_issues.test.cjs"

# Expected: Tests should pass
# close_older_issues.test.cjs (15 tests) ✓

Investigation completed: 2026-01-20T20:00:00Z
Pattern stored: /tmp/gh-aw/cache-memory/investigations/2026-01-20-21185259940.json
Error Pattern: MODULE_NOT_FOUND_JEST_GLOBALS
Severity: High (blocks CI)
Complexity: Low (straightforward find-replace fix)
Automated Fix: Possible (systematic replacement of Jest with Vitest syntax)

AI generated by CI Failure Doctor

To add this workflow in your repository, run gh aw add githubnext/agentics/workflows/ci-doctor.md@ea350161ad5dcc9624cf510f134c6a9e39a6f94d. See usage guide.

Activity

  1. github-actions commented on Jan 20, 2026

    @github-actions
    ContributorAuthor

    🔄 Duplicate Failure - Run #21185331298

    This issue has caused another CI failure:

    🔍 Investigation Findings

    Scope Confirmation

    I've verified that only one file in the entire test suite uses Jest syntax:

    • close_older_issues.test.cjs is the only file using @jest/globals
    • close_older_issues.test.cjs is the only file using jest.fn()
    • All other 60+ test files correctly use Vitest syntax

    Correct Pattern (from other test files)

    // ✅ CORRECT - Vitest syntax
    import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
    
    // Use vi.fn() instead of jest.fn()
    const mockFunction = vi.fn();
    
    // Use vi.clearAllMocks() instead of jest.clearAllMocks()
    beforeEach(() => {
      vi.clearAllMocks();
    });

    Current Incorrect Pattern

    // ❌ INCORRECT - Jest syntax (from close_older_issues.test.cjs)
    const { describe, it, expect, beforeEach } = require("@jest/globals");
    
    // Wrong - uses jest.fn()
    global.core = {
      info: jest.fn(),
      warning: jest.fn(),
      error: jest.fn(),
    };
    
    // Wrong - uses jest.clearAllMocks()
    beforeEach(() => {
      jest.clearAllMocks();
    });

    🛠️ Recommended Fix

    Convert close_older_issues.test.cjs to use Vitest syntax:

    1. Change import statement:

      // From:
      const { describe, it, expect, beforeEach } = require("@jest/globals");
      
      // To:
      import { describe, it, expect, beforeEach, vi } from "vitest";
    2. Replace all jest.fn() with vi.fn()

    3. Replace all jest.clearAllMocks() with vi.clearAllMocks()

    4. Replace all .mockResolvedValue() with .mockResolvedValue() (Vitest compatible)

    5. Replace all .mockRejectedValue() with .mockRejectedValue() (Vitest compatible)

    🚨 Impact

    This bug is blocking all CI runs on the main branch. Every push triggers the same failure, preventing:

    • All other CI checks from being meaningful
    • Deployment of new features
    • Merge of new PRs (if CI is required)

    📋 AI Team Self-Improvement Prompt

    To prevent this type of failure in the future, add this to AI coding agent instructions:

    ### JavaScript Testing Framework
    
    **CRITICAL**: This codebase uses **Vitest**, NOT Jest.
    
    When creating or modifying test files (`*.test.cjs`):
    - ✅ **ALWAYS use**: `import { describe, it, expect, beforeEach, vi } from "vitest"`
    - ✅ **ALWAYS use**: `vi.fn()` for mocking functions
    - ✅ **ALWAYS use**: `vi.clearAllMocks()` for clearing mocks
    - ❌ **NEVER use**: `@jest/globals`, `jest.fn()`, `jest.clearAllMocks()`
    - ❌ **NEVER add**: Jest as a dependency in `package.json`
    
    **Before committing test changes**:
    ``````bash
    make fmt-cjs      # Format JavaScript files
    make test-unit    # Run unit tests to verify

    Reference any existing test file in actions/setup/js/*.test.cjs as a template.

    
    ## 🔗 Related Information
    
    - Package.json confirms: `"vitest": "^4.0.10"` (NO Jest dependency)
    - Test command: `npm test` runs `vitest run --no-file-parallelism`
    - File was likely added by an AI coding agent unfamiliar with the project's testing framework choice
    
    > AI generated by [CI Failure Doctor](https://github.com/githubnext/gh-aw/actions/runs/21185491970)
    
  2. github-actions commented on Jan 20, 2026

    @github-actions
    ContributorAuthor

    🍪 Issue Monster has assigned this to Copilot!

    I've identified this issue as a good candidate for automated resolution and assigned it to the Copilot agent.

    The Copilot agent will analyze the issue and create a pull request with the fix.

    Om nom nom! 🍪

    AI generated by Issue Monster

  3. github-actions commented on Jan 20, 2026

    @github-actions
    ContributorAuthor

    🔄 Duplicate Failure Detected - Run #21187161778

    This CI run failed with the SAME Jest/Vitest incompatibility issue as originally reported in this issue.

    Run Details

    Error Details

    Identical error as originally reported:

    Error: Cannot find module '@jest/globals'
    Require stack:
    - /home/runner/work/gh-aw/gh-aw/actions/setup/js/close_older_issues.test.cjs
     ❯ close_older_issues.test.cjs:3:46
    

    Context

    This failure occurred as part of a massive PR #10900 that added 330+ files. The PR merged successfully despite this test file still having Jest syntax incompatibility issues.

    Additional Failures in Same Run

    This run also had 41 additional test failures unrelated to the Jest/Vitest issue:

    1. 36 validation test failures in collect_ndjson_output.test.cjs (validation regression - duplicate of closed issue [CI Failure Doctor] JS validation regression after PR #10125 - 43 tests failing #10137)
    2. 2 timeout failures in safe_outputs_mcp_server_defaults.test.cjs (MCP server branch parameter tests)

    See full investigation report: /tmp/investigation/reports/full-investigation.md (available in workflow artifacts if needed)

    Impact

    Status: Issue persists on main branch
    Severity: CRITICAL - blocking all CI runs on main branch
    Duration: ~2 hours since issue opened, still not fixed

    Recommended Fix

    Same as originally identified - convert Jest syntax to Vitest:

    - const { describe, it, expect, beforeEach } = require("@jest/globals");
    + const { describe, it, expect, beforeEach, vi } = require("vitest");
    
    - jest.fn()
    + vi.fn()
    
    - jest.clearAllMocks()
    + vi.clearAllMocks()

    Investigation by CI Failure Doctor

    AI generated by CI Failure Doctor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions