Skip to content

fix(eve): return tool errors as execute results - #108

Merged
HugoRCD merged 2 commits into
mainfrom
fix/eve-tool-error-result
Aug 26, 2026
Merged

fix(eve): return tool errors as execute results#108
HugoRCD merged 2 commits into
mainfrom
fix/eve-tool-error-result

Conversation

@HugoRCD

@HugoRCD HugoRCD commented Aug 26, 2026

Copy link
Copy Markdown
Member

Summary

  • Eve GitHub execute now returns { error } on failure instead of throwing.
  • Eve's tool-loop logs thrown execute errors (tool execution failed) but does not always append a tool_result, so the next model call dies with MODEL_CALL_FAILED (tool_use without tool_result).
  • Token mint failures, GitHub 403/429, and other core throws stay visible to the model as a normal tool result.

Stacked on the Connect OIDC PR (this branch → fix/connect-oidc-env-tokenevl-343main).

Approval deny and the stale World Event id is not slot-numbered spam are still eve/world-local — not fixable in this repo.

Test plan

  • pnpm --filter @github-tools/sdk test
  • Force a token failure in examples/eve and confirm the turn continues with { error } instead of MODEL_CALL_FAILED
  • Confirm a successful tool still returns its normal payload

@vercel

vercel Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
github-tools-docs Ready Ready Preview, v0 Aug 26, 2026 9:43am
github-tools-test-agent Ready Ready Preview, v0 Aug 26, 2026 9:43am

@github-actions

Copy link
Copy Markdown
Contributor

Thank you for following the naming conventions! 🙏

Comment thread packages/github-tools/src/eve/steps.ts
Base automatically changed from fix/connect-oidc-env-token to main August 26, 2026 09:41
Eve's tool-loop logs thrown execute errors without always appending a tool_result, which Anthropic rejects as MODEL_CALL_FAILED. Return { error } so the pairing stays intact.
…runGithubToolStep` returns `{ error }`, and `listPullRequestFilesToModelOutput` calls `.map` on that object, throwing `TypeError: files.map is not a function` inside model-output formatting.

This commit fixes the issue reported at packages/github-tools/src/eve/steps.ts:28

## Bug

`runGithubToolStep` (`packages/github-tools/src/eve/steps.ts`) was changed to catch execute failures and return an error payload instead of throwing:

```ts
} catch (error) {
  return { error: error instanceof Error ? error.message : String(error) }
}
```

Both eve wiring paths pass the `execute` return value into `toModelOutput`:

*   `build.ts` (`buildEveToolDefinition` / `buildEveToolMap`): `toModelOutput: (output) => formatGithubEveToolOutput(name, output)`
*   `executeGithubEveTool` (used by `@github-tools/eve-extension`) returns the same `runGithubToolStep` result, which eve then feeds to `toModelOutput`.

`formatGithubEveToolOutput` (`registry.ts`) strips `rateLimit` then dispatches to a per-tool formatter. `stripRateLimit({ error })` leaves the object unchanged (no `rateLimit` key). For `listPullRequestFiles` it dispatches to `listPullRequestFilesToModelOutput` (`core/model-output.ts`):

```ts
export function listPullRequestFilesToModelOutput({ output }) {
  const files = output as ListPullRequestFilesOutput
  return { type: 'json', value: truncatePatchFields(files) } // files.map(...)
}
```

**Trigger:** any failed `listPullRequestFiles` call (e.g. GitHub 404/403, network error). The failure produces `output = { error: '...' }`, an object, so `truncatePatchFields(files)` → `files.map(...)` throws `TypeError: files.map is not a function`. This throws *inside model-output formatting*, re-breaking the tool loop and defeating the whole point of returning a payload (preserving `tool_use`/`tool_result` pairing).

The other array formatters (`getCommit`, `compareCommits`, `getPullRequestContext`) guard `files` with a ternary, and `getFileContent` guards with `'content' in result`, so `listPullRequestFiles` is the one that crashes on the top-level payload. (The others would still return an error payload verbatim, but wouldn't crash.)

## Fix

Short-circuit in `formatGithubEveToolOutput` — the single dispatch point shared by all paths — when the (rate-limit-stripped) output is an `{ error: string }` payload, returning it as `{ type: 'json', value }` without running the success-shaped formatter:

```ts
if (isErrorPayload(stripped)) {
  return { type: 'json', value: stripped }
}
```

`isErrorPayload` matches a non-array object with a string `error` field. This is safe because none of the GitHub tool success outputs carry a top-level `error: string` field. Typecheck (`tsc --noEmit`) passes.


Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
Co-authored-by: HugoRCD <hugo.richard@vercel.com>
@HugoRCD
HugoRCD merged commit 5bbcab1 into main Aug 26, 2026
14 checks passed
@HugoRCD
HugoRCD deleted the fix/eve-tool-error-result branch August 26, 2026 09:50
@github-actions github-actions Bot mentioned this pull request Aug 26, 2026
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.

1 participant