# How to Debug *verify-subtask Failures Across Different Verification Types in aiox-core

> Debug *verify-subtask failures in aiox-core by enabling the verbose flag and inspecting verification blocks in implementation.yaml. Get clear error insights fast.

- Repository: [SynkraAI/aiox-core](https://github.com/synkraai/aiox-core)
- Tags: how-to-guide
- Published: 2026-03-15

---

**Enable the `--verbose` flag and inspect the `verification` block in your [`implementation.yaml`](https://github.com/SynkraAI/aiox-core/blob/main/implementation.yaml) to surface the exact error from the command, API, browser, or e2e runner.**

When `*verify-subtask` fails in the SynkraAI/aiox-core repository, the root cause typically hides inside the **verification configuration** or the **type-specific runner** dispatched by the `SubtaskVerifier` class. This guide walks you through a systematic debugging workflow that works for **command**, **api**, **browser**, and **e2e** verification types.

## Understand the Verification Flow

The `*verify-subtask` logic lives in [`.aiox-core/infrastructure/scripts/subtask-verifier.js`](https://github.com/SynkraAI/aiox-core/blob/main/.aiox-core/infrastructure/scripts/subtask-verifier.js). The high-level execution flow follows these steps:

1. **Load implementation** via `loadImplementation()` parsing [`implementation.yaml`](https://github.com/SynkraAI/aiox-core/blob/main/implementation.yaml)
2. **Locate subtask** via `findSubtask()` using the provided ID
3. **Read verification metadata** (type, command, URL, selector, etc.)
4. **Dispatch to runner** via `_runVerification()` which calls one of four private methods: `_verifyCommand`, `_verifyApi`, `_verifyBrowser`, or `_verifyE2E`

```js
// Dispatch based on verification.type
// Source: subtask-verifier.js, lines 46-50
await this._runVerification(verification);

```

Each runner returns an object with `{passed, output?, error?}`. If `passed` is `false`, the verifier wraps the failure with the subtask ID, verification type, attempt count, and error message, then generates a report via `generateReport()`.

## Enable Verbose Logging

The `SubtaskVerifier` captures every step in an internal `logs` array through the `_log()` method. By default these logs are silent; enabling `--verbose` (`-v`) prints timestamps, command outputs, API status codes, Playwright navigation events, and retry delays to the console.

```bash
subtask-verifier 1.1 -i docs/stories/STORY-42/plan/implementation.yaml -v

```

All verbose output also appears in the final report under the **Logs** section, making it the first diagnostic tool to enable when a verification fails.

## Debug Failures by Verification Type

### Command Verification Failures

*Implementation*: `_verifyCommand()` at lines 68-98 of [`subtask-verifier.js`](https://github.com/SynkraAI/aiox-core/blob/main/subtask-verifier.js).

**Common symptoms and fixes:**

- **"Exit code 1" or non-zero exit**: The `command` string in the subtask's `verification` block contains a wrong path, missing binary, or permission error. Re-run the command manually in the same working directory (`--cwd` defaults to `process.cwd()`).
- **"Command timed out"**: The process exceeds the default 60-second timeout. Increase the limit with `--timeout <ms>` or optimize the script.
- **"No output captured"**: The script writes only to stderr or uses streaming output. The verifier captures both `stdout` and `stderr`; inspect the `output` field in the failure report.

Compare the manual command output against the verifier's log entries (look for `_log('Running command…')`) to isolate environment differences.

### API Verification Failures

*Implementation*: `_verifyApi()` at lines 33-41 of [`subtask-verifier.js`](https://github.com/SynkraAI/aiox-core/blob/main/subtask-verifier.js).

**Common symptoms and fixes:**

- **"Expected status 200, got 500"**: The endpoint is unreachable or the server returned an error. Verify reachability with `curl` or a browser.
- **"Output did not match pattern"**: The `expectedOutput` regex fails against the response body. Test your regex manually: `node -e "console.log(/pattern/.test(JSON.stringify(response)))"`.
- **"Request timed out"**: Network latency or firewall rules block the request. Increase `--timeout` or test with `curl --max-time`.
- **"fetch is undefined"**: You are running Node.js < 18 without native fetch. Install `node-fetch` or upgrade Node.

The verifier logs the **URL**, **method**, and **status** via `_log('Calling API…')`. Replicate the exact request with matching headers to see the raw response.

### Browser Verification Failures

*Implementation*: `_verifyBrowser()` (method starts at line 4 of its definition block).

**Common symptoms and fixes:**

- **"Browser verification requires Playwright"**: The Playwright dependency is missing. Install with `npm i playwright` or `npx playwright install`.
- **"Selector not found"**: The CSS or XPath selector is invalid or the page loads too slowly. Open the target URL in a browser, inspect the element, and verify the selector syntax.
- **"Expected text not found"**: Dynamic content renders after the check. Add `waitForSelector` or increase `config.timeout` in the verification block.
- **"Navigation failed / network idle timeout"**: Page redirects, authentication walls, or CSP headers block automation. Check console logs for navigation errors; temporarily add `page.screenshot()` to the verification config to capture the UI state.

The verifier prints "Running browser verification with Playwright…" followed by the target URL and selector checks. Copy the Playwright block from [`subtask-verifier.js`](https://github.com/SynkraAI/aiox-core/blob/main/subtask-verifier.js) into a local script to step through each action interactively.

### E2E Verification Failures

*Implementation*: `_verifyE2E()` at lines 78-89, which forwards to `_verifyCommand()` using the `testCommand` parameter.

**Debugging approach:**

Since E2E delegates to the command runner, follow the same steps as **Command Verification**. Additionally, run the `testCommand` manually (e.g., `npm run test:e2e`) and confirm the test runner returns exit code **0** on success. Check for Jest, Playwright Test, or other framework-specific errors in the captured output.

## Adjust Retry Logic for Transient Errors

`SubtaskVerifier` retries failed attempts up to `maxRetries` (default 3). Retries only occur when `_isTransientError(error)` returns `true`, matching patterns like *ECONNRESET*, *ETIMEDOUT*, or *ECONNREFUSED* (see lines 96-105).

If verification fails after all retries, the final report shows the **attempt count** and **last error**. Increase resilience against flaky networks or CI resource contention by adjusting the retry and timeout parameters:

```bash
subtask-verifier 1.2 -i impl.yaml --retries 5 --timeout 120000

```

## Use Programmatic Debugging

Embed the `SubtaskVerifier` class directly in a Node.js script to capture the raw `VerificationResult` object for inspection:

```js
// file: debug-subtask.js
const { SubtaskVerifier } = require('./.aiox-core/infrastructure/scripts/subtask-verifier');

(async () => {
  const verifier = new SubtaskVerifier({
    implementationPath: 'docs/stories/STORY-42/plan/implementation.yaml',
    verbose: true,
  });

  const result = await verifier.verify('1.1');  // <- subtask ID
  console.log(JSON.stringify(result, null, 2)); // inspect error, output, attempts
})();

```

The returned object follows the JSDoc shape defined at lines 44-53 of [`subtask-verifier.js`](https://github.com/SynkraAI/aiox-core/blob/main/subtask-verifier.js), exposing `result.error`, `result.output`, `result.attempts`, and other metadata for automated analysis.

## Summary

- The `*verify-subtask` command delegates to four type-specific runners (`_verifyCommand`, `_verifyApi`, `_verifyBrowser`, `_verifyE2E`) inside [`.aiox-core/infrastructure/scripts/subtask-verifier.js`](https://github.com/SynkraAI/aiox-core/blob/main/.aiox-core/infrastructure/scripts/subtask-verifier.js).
- Enable `-v` to expose timestamps, API status codes, Playwright actions, and command output in the failure report.
- For each verification type, validate the underlying action manually (run the shell command, `curl` the endpoint, open the browser URL, execute the test suite) before adjusting configuration.
- Increase `--timeout` and `--retries` when encountering transient network or resource errors detected by `_isTransientError()`.
- Use the programmatic API to capture raw `VerificationResult` objects for custom CI integrations or deep debugging.

## Frequently Asked Questions

### How do I identify which verification type is failing?

Check the **Error** line in the generated report or the verbose logs. The `SubtaskVerifier` logs the verification type via `_runVerification()` before dispatching to `_verifyCommand`, `_verifyApi`, `_verifyBrowser`, or `_verifyE2E`. The subtask's `verification` block in [`implementation.yaml`](https://github.com/SynkraAI/aiox-core/blob/main/implementation.yaml) also explicitly declares the `type` field.

### Why does my API verification fail with "fetch is undefined"?

The [`subtask-verifier.js`](https://github.com/SynkraAI/aiox-core/blob/main/subtask-verifier.js) script uses the native Node.js `fetch` API. If you see this error, you are running Node.js version < 18. Upgrade to Node 18+ or install a fetch polyfill (`npm i node-fetch`) to resolve the issue.

### Can I increase the timeout for a single slow subtask without affecting others?

Yes. Pass the `--timeout` flag with a millisecond value when invoking the CLI for that specific subtask: `subtask-verifier <id> -i <yaml> --timeout 120000`. This overrides the default 60-second limit for that execution only.

### Where can I find the raw output from a failed command verification?

The `VerificationResult` object includes an `output` field containing both `stdout` and `stderr`. When running programmatically, inspect `result.output`. When using the CLI with `-v`, the logs section of the report prints the captured output immediately after the `_log('Running command…')` entry.