Skip to content

[CI Failure Doctor] TypeScript type error in handle_agent_failure.cjs - boolean passed to renderTemplate #10427

@github-actions

Description

@github-actions

🏥 CI Failure Investigation - Run #21089288909

Summary

The CI workflow failed due to TypeScript type errors in handle_agent_failure.cjs. The code passes a boolean value (secret_verification_failed) to the renderTemplate() function, which expects only string | number | undefined types.

Failure Details

Root Cause Analysis

Error Messages

handle_agent_failure.cjs:292:61 - error TS2345: Argument of type '{ ...; secret_verification_failed: boolean; ... }' is not assignable to parameter of type 'Record<string, string | number | undefined>'.
  Property 'secret_verification_failed' is incompatible with index signature.
    Type 'boolean' is not assignable to type 'string | number | undefined'.

292         const commentBody = renderTemplate(commentTemplate, templateContext);
                                                                ~~~~~~~~~~~~~~~

handle_agent_failure.cjs:338:64 - error TS2345: [Same error at different location]
338         const issueBodyContent = renderTemplate(issueTemplate, templateContext);
                                                                   ~~~~~~~~~~~~~~~

Technical Details

The renderTemplate() function in messages_core.cjs (line 69) has the following signature:

function renderTemplate(template: string, context: Record<string, string|number|undefined>): string

However, handle_agent_failure.cjs creates template contexts with a boolean field:

Line 286-289 (Comment context):

const templateContext = {
  // ... other string fields ...
  secret_verification_failed: secretVerificationResult === "failed",  // ❌ boolean
  secret_verification_context: secretVerificationResult === "failed" ? "\n**⚠️ ...\n" : "",
};

Line 325-335 (Issue context):

const templateContext = {
  // ... other string fields ...
  secret_verification_failed: secretVerificationResult === "failed",  // ❌ boolean
  secret_verification_context: secretVerificationResult === "failed" ? "\n**⚠️ ...\n" : "",
};

Why This Wasn't Caught Earlier

  1. The JavaScript code is syntactically valid - the type error only appears during TypeScript compilation
  2. The npm test command runs npm run typecheck && vitest run --no-file-parallelism
  3. TypeScript's tsc --noEmit check is run before tests, catching the type error
  4. The PR Store secret verification result in step/job output for agent failure context #10408 added the secret_verification_failed field but didn't account for TypeScript's type constraints

Recommended Actions

Fix #1: Convert Boolean to String (Recommended)

Change the boolean to a string representation:

// Line 286
const templateContext = {
  run_url: runUrl,
  run_id: runId,
  workflow_name: workflowName,
  workflow_source: workflowSource,
  workflow_source_url: workflowSourceURL,
  secret_verification_failed: String(secretVerificationResult === "failed"),  // ✅ Convert to string
  secret_verification_context:
    secretVerificationResult === "failed" ? "\n**⚠️ Secret Verification Failed**: ...\n" : "",
};

// Line 325
const templateContext = {
  workflow_name: sanitizedWorkflowName,
  run_url: runUrl,
  workflow_source_url: workflowSourceURL || "#",
  branch: currentBranch,
  pull_request_info: pullRequest ? `  \n**Pull Request:** [#${pullRequest.number}](${pullRequest.html_url})` : "",
  secret_verification_failed: String(secretVerificationResult === "failed"),  // ✅ Convert to string
  secret_verification_context:
    secretVerificationResult === "failed" ? "\n**⚠️ Secret Verification Failed**: ...\n" : "",
};

Fix #2: Update renderTemplate Type Signature (Alternative)

Alternatively, update renderTemplate() to accept booleans:

// messages_core.cjs, line 66
function renderTemplate(template: string, context: Record<string, string|number|boolean|undefined>): string {
  return template.replace(/\{(\w+)\}/g, (match, key) => {
    const value = context[key];
    return value !== undefined && value !== null ? String(value) : match;
  });
}

Recommendation: Fix #1 is preferred because it's more explicit and maintains stricter type safety.

Prevention Strategies

1. Pre-commit Hooks

Add TypeScript type checking to pre-commit hooks:

# In .git/hooks/pre-commit or via husky
cd actions/setup/js && npm run typecheck

2. GitHub Actions Job Order

The js job already runs npm test which includes typecheck. The issue is that other jobs don't depend on it. Consider making critical jobs depend on the js job:

build:
  needs: js  # Wait for js tests to pass
  runs-on: ubuntu-latest
  # ...

3. Local Development Workflow

Update make agent-finish or create a new make target to include JS type checking:

.PHONY: test-js
test-js:
	cd actions/setup/js && npm ci && npm test

.PHONY: agent-finish
agent-finish: build test test-js recompile fmt lint
	@echo "✅ All checks passed"

AI Team Self-Improvement

Instructions to add to AGENTS.md or developer documentation:

### JavaScript Type Safety

**ALWAYS ensure TypeScript type compatibility when passing objects to functions:**

When working with `renderTemplate()` or similar type-constrained functions:

1. **Check function signature**: Review the TypeScript types in `messages_core.cjs` or type definition files
2. **Convert types explicitly**: Use `String(booleanValue)` to convert booleans to strings
3. **Run typecheck locally**: Execute `cd actions/setup/js && npm run typecheck` before committing
4. **Test command includes typecheck**: The `npm test` command runs TypeScript type checking first

**Example - Correct usage:**
```javascript
const context = {
  secret_verification_failed: String(result === "failed"),  // ✅ Explicit conversion
  secret_verification_context: result === "failed" ? "Error message" : "",
};
const output = renderTemplate(template, context);

Example - Incorrect usage:

const context = {
  secret_verification_failed: result === "failed",  // ❌ Boolean not allowed
};
const output = renderTemplate(template, context);

## Historical Context

This is a new type of failure pattern. Previous CI failures in this repository have been related to:
- Test failures
- Lint errors  
- Build issues
- Integration test timeouts

This is the **first TypeScript type mismatch error** in the JavaScript codebase to reach the main branch, indicating that type checking may not be consistently enforced across all development workflows.

## Files Affected

- `actions/setup/js/handle_agent_failure.cjs` (lines 286-289, 325-335)
- `actions/setup/js/messages_core.cjs` (type definition reference)

## Related Changes

PR #10408 introduced secret verification result outputs:
- Modified `validate_multi_secret.sh` to set step output
- Added `secret_verification_result` output to agent job
- Passed verification result to conclusion job
- Updated `handle_agent_failure.cjs` to use the result ← **This is where the type error was introduced**

---

**Investigation completed**: 2026-01-17T05:42:00Z  
**Pattern stored**: `/tmp/gh-aw/cache-memory/investigations/2026-01-17-21089288909.json`




> AI generated by [CI Failure Doctor](https://github.com/githubnext/gh-aw/actions/runs/21089358482)
>
> To add this workflow in your repository, run `gh aw add githubnext/agentics/workflows/ci-doctor.md@ea350161ad5dcc9624cf510f134c6a9e39a6f94d`. See [usage guide](https://githubnext.github.io/gh-aw/guides/packaging-imports/).

<!-- agentic-workflow: CI Failure Doctor, engine: copilot, run: https://github.com/githubnext/gh-aw/actions/runs/21089358482 -->

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions