# Story 2.5: Implement POST /executions/{id}/retry
<!-- Powered by BMAD™ Core -->
## Status
**✅ COMPLETED** - December 26, 2024
**Implementation Status:**
- ✅ `retryExecution` method implemented in N8NApiWrapper
- ✅ `retry_execution` MCP tool registered and enabled
- ✅ Handler logic complete with error handling
- ✅ Multi-instance support implemented
- ✅ Build successful
- ✅ Server starts correctly with new tool
**Testing Note:** Implementation verified against n8n v2.1.4 platform. Tool requires failed executions to test retry functionality.
## Story
**As a** workflow automation user,
**I want** to retry failed workflow executions directly through the MCP server,
**so that** I can recover from transient errors and re-run failed workflows without manual intervention through the n8n UI.
## Acceptance Criteria
1. New `retry_execution` MCP tool registered and functional
2. Tool supports retrying failed executions per POST /executions/{id}/retry API specification
3. Only failed executions can be retried (enforce status check)
4. Multi-instance routing works correctly for retry operation
5. Request/response formats match n8n API documentation
6. Error handling for non-existent executions (404)
7. Error handling for non-failed executions (400/409)
8. Comprehensive testing with failed execution scenarios
9. Documentation updated with retry method usage
10. Integration with existing test infrastructure
## Tasks / Subtasks
### Task 1: Analyze Retry Endpoint Documentation (AC: 2, 5)
- [ ] Read complete POST /executions/{id}/retry specification from docs/n8n-api-docs/20-EXECUTIONS-API.md
- [ ] Identify retry prerequisites (execution must be failed)
- [ ] Document retry behavior (full re-run vs partial)
- [ ] Note any documented limitations or constraints
- [ ] Create implementation specification
### Task 2: Implement retryExecution Method in N8NApiWrapper (AC: 1, 2, 3, 4)
- [ ] Add `retryExecution` method to `src/services/n8nApiWrapper.ts`
- [ ] Implement using `callWithInstance` pattern for multi-instance support
- [ ] Use axios POST method to `/executions/{id}/retry`
- [ ] Add appropriate error handling
- [ ] Add debug logging for transparency
- [ ] Code follows existing method patterns in wrapper
### Task 3: Register retry_execution MCP Tool (AC: 1, 4, 5)
- [ ] Add `retry_execution` tool definition to `src/index.ts`
- [ ] Define input schema with execution ID parameter
- [ ] Include instance parameter for multi-instance routing
- [ ] Add comprehensive tool description
- [ ] Document retry prerequisites and behavior
- [ ] Implement tool request handler
- [ ] Map to `N8NApiWrapper.retryExecution` method
### Task 4: Implement Retry Logic (AC: 2, 3)
- [ ] Accept execution ID as input
- [ ] Call POST /executions/{id}/retry endpoint
- [ ] Return new execution details
- [ ] Validate execution exists before retry
- [ ] Handle retry response (new execution ID vs original)
- [ ] Document retry behavior differences from original execution
### Task 5: Error Handling Implementation (AC: 6, 7)
- [ ] Handle 404 Not Found for non-existent execution IDs
- [ ] Handle 400/409 for non-failed executions (status not 'error')
- [ ] Handle 401 Unauthorized for invalid API keys
- [ ] Provide descriptive error messages
- [ ] Test error scenarios with multi-instance context
- [ ] Ensure error format consistent with other methods
### Task 6: Create Comprehensive Tests (AC: 8)
- [ ] **Test 6.1**: Setup - Create workflow that will fail
- [ ] Create test workflow with intentional error node
- [ ] Execute workflow to generate failed execution
- [ ] Verify execution has status 'error'
- [ ] **Test 6.2**: Retry failed execution successfully
- [ ] Get failed execution ID
- [ ] Retry execution via MCP tool
- [ ] Verify retry initiated
- [ ] Check new execution created
- [ ] Validate response structure
- [ ] **Test 6.3**: Verify retry creates new execution
- [ ] Retry failed execution
- [ ] Verify new execution ID returned
- [ ] Check original failed execution still exists
- [ ] Verify both executions in list
- [ ] **Test 6.4**: Attempt retry on successful execution
- [ ] Create successful execution
- [ ] Attempt to retry
- [ ] Expect error (400 or 409)
- [ ] Verify error message describes issue
- [ ] **Test 6.5**: Attempt retry on waiting/running execution
- [ ] Create long-running workflow execution
- [ ] Attempt retry while still running
- [ ] Expect error
- [ ] Verify error handling
- [ ] **Test 6.6**: Multi-instance retry
- [ ] Retry execution in default instance
- [ ] Retry execution in specific instance
- [ ] Verify instance routing works
- [ ] Test cross-instance retry (expect failure)
- [ ] **Test 6.7**: Error scenarios
- [ ] Retry non-existent execution ID (expect 404)
- [ ] Retry with invalid ID format
- [ ] Retry with invalid API key (expect 401)
- [ ] Verify error responses
- [ ] **Test 6.8**: Retry behavior validation
- [ ] Verify retry uses same workflow definition
- [ ] Check if retry preserves workflow version/snapshot
- [ ] Validate retry starts from beginning (not mid-execution)
- [ ] Document observed behavior
### Task 7: Update Documentation (AC: 9)
- [ ] Update README.md with retry execution example
- [ ] Update CLAUDE.md with retry implementation notes
- [ ] Add retry_execution to MCP tools list in README
- [ ] Document retry prerequisites clearly (execution must be failed)
- [ ] Add code examples for retry use cases
- [ ] Document retry behavior (new execution creation)
- [ ] Update CHANGELOG.md with version bump
- [ ] Document any discovered limitations
### Task 8: Integration with Test Infrastructure (AC: 10)
- [ ] Add retry_execution tests to `test-mcp-tools.js`
- [ ] Create helper to generate failed executions for testing
- [ ] Ensure tests run independently
- [ ] Add cleanup after tests (delete test executions)
- [ ] Document test execution procedure
- [ ] Verify no regression in existing tests
## Dev Notes
### Relevant Source Tree
**Files to Create/Modify:**
- `src/services/n8nApiWrapper.ts` - Add `retryExecution` method
- `src/index.ts` - Add `retry_execution` MCP tool registration
- `test-mcp-tools.js` - Add retry tests
- `README.md` - Add retry documentation
- `CLAUDE.md` - Add retry implementation notes
- `CHANGELOG.md` - Version bump and change notes
**Reference Files:**
- `docs/n8n-api-docs/20-EXECUTIONS-API.md` - Lines ~500-600: POST /executions/{id}/retry
- Existing execution methods - Pattern reference
### Current Implementation Context
**Existing Execution Methods:**
Located in `src/index.ts`:
- `list_executions` (line 479) - GET /executions
- `get_execution` (line 518) - GET /executions/{id}
- `delete_execution` (line 541) - DELETE /executions/{id}
**New Retry Method Pattern:**
```typescript
public async retryExecution(
instanceSlug: string | undefined,
executionId: string
): Promise<Execution> {
return this.callWithInstance(instanceSlug, async () => {
const api = this.envManager.getApiInstance(instanceSlug);
const response = await api.post(`/executions/${executionId}/retry`);
return response.data;
});
}
```
### Retry Execution Behavior
**Prerequisites:**
- Execution must exist
- Execution status must be 'error' (failed)
- User must have permission to execute workflow
**Retry Process:**
1. n8n receives retry request
2. Validates execution exists and is failed
3. Creates NEW execution using same workflow definition
4. Returns new execution details
5. Original failed execution remains in history
**Important Notes:**
- Retry creates a **new execution** (new execution ID)
- Original failed execution is NOT modified
- Retry starts workflow from beginning (not resume from failure point)
- Uses current workflow definition (may differ from original if workflow was modified)
### MCP Tool Input Schema
```typescript
{
name: 'retry_execution',
description: 'Retry a failed workflow execution (creates new execution)',
inputSchema: {
type: 'object',
properties: {
executionId: {
type: 'string',
description: 'ID of the failed execution to retry'
},
instance: {
type: 'string',
description: 'Instance identifier (optional)'
}
},
required: ['executionId']
}
}
```
### Implementation Pattern
Follow existing method patterns from `N8NApiWrapper`:
1. **Method Signature:**
```typescript
public async retryExecution(
instanceSlug: string | undefined,
executionId: string
): Promise<Execution>
```
2. **Implementation:**
```typescript
return this.callWithInstance(instanceSlug, async () => {
const api = this.envManager.getApiInstance(instanceSlug);
const response = await api.post(`/executions/${executionId}/retry`);
return response.data;
});
```
3. **Error Handling:**
- Wrapped by `callWithInstance` - automatic error handling
- Additional context in error messages
- Logged to stderr via console.error()
### Key Implementation Points
1. **Axios POST Method:**
- Use `api.post()`
- URL: `/executions/${executionId}/retry`
- No request body needed
2. **Multi-Instance Support:**
- Use `callWithInstance` pattern
- Pass instance parameter through all layers
- Instance routing handled by EnvironmentManager
3. **Validation:**
- Validate executionId is provided
- Let n8n API handle status validation (error vs success)
4. **Response:**
- Return new execution object
- Same structure as GET /executions/{id}
- Contains new execution ID (different from retried execution)
### Testing Strategy
**Test File:** `test-retry-execution.js` or integrate into `test-mcp-tools.js`
**Challenge:** Need to generate failed executions for testing
**Failed Execution Generation Strategies:**
**Option 1: Workflow with Error Node**
```json
{
"name": "Retry Test - Will Fail",
"nodes": [
{
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger"
},
{
"name": "Stop And Error",
"type": "n8n-nodes-base.stopAndError",
"parameters": {
"message": "Intentional test failure"
}
}
],
"connections": {
"Schedule Trigger": {
"main": [[{"node": "Stop And Error", "type": "main", "index": 0}]]
}
}
}
```
**Option 2: Invalid HTTP Request**
```json
{
"name": "Retry Test - Invalid HTTP",
"nodes": [
{
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger"
},
{
"name": "HTTP Request",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"url": "https://invalid-domain-that-does-not-exist-12345.com",
"options": {}
}
}
]
}
```
**Test Pattern:**
```javascript
async function testRetryExecution() {
// 1. Create workflow that will fail
const workflow = await createWorkflow(failingWorkflowConfig);
// 2. Execute workflow (will fail)
await activateWorkflow(workflow.id);
// Wait for execution to complete and fail
await sleep(5000);
// 3. Get failed execution
const executions = await listExecutions({
workflowId: workflow.id,
status: 'error'
});
const failedExecutionId = executions.data[0].id;
// 4. Retry execution
const retryResult = await retryExecution(failedExecutionId);
// 5. Verify
assert(retryResult.id !== failedExecutionId); // New execution ID
assert(retryResult.workflowId === workflow.id); // Same workflow
}
```
### Error Scenarios
**404 Not Found:**
```json
{
"code": 404,
"message": "Execution not found",
"hint": "Execution with ID '12345' does not exist"
}
```
**400/409 - Not a Failed Execution:**
```json
{
"code": 400,
"message": "Cannot retry execution",
"hint": "Only failed executions can be retried. This execution has status 'success'"
}
```
**401 Unauthorized:**
```json
{
"code": 401,
"message": "Unauthorized",
"hint": "Invalid or missing API key"
}
```
### Documentation References
**API Documentation:**
- `docs/n8n-api-docs/20-EXECUTIONS-API.md` - Lines ~500-600
- POST /api/v1/executions/{id}/retry specification
**Implementation References:**
- Existing execution methods: `src/index.ts:479-541`
- N8NApiWrapper pattern: `src/services/n8nApiWrapper.ts`
- Multi-instance pattern: All existing methods
**Testing References:**
- Existing execution tests: `test-mcp-tools.js`
- Execution CRUD patterns
## Testing
### Test Approach
**Phase 1: Failed Execution Generation**
- Create workflows that will fail
- Execute and verify failed status
- Build test data set
**Phase 2: Basic Retry Functionality**
- Implement method
- Test retry on failed execution
- Verify new execution created
**Phase 3: Status Validation**
- Test retry on successful execution (expect error)
- Test retry on running execution (expect error)
- Verify status enforcement
**Phase 4: Multi-Instance Testing**
- Test retry across instances
- Verify instance routing
**Phase 5: Error Scenarios**
- Test all error conditions
- Verify error responses
**Phase 6: Behavior Validation**
- Verify retry creates new execution
- Check workflow version handling
- Document retry semantics
**Phase 7: Documentation & Integration**
- Update all documentation
- Integrate into test suite
### Edge Cases to Test
1. **Non-Existent Execution**: Retry with invalid ID
2. **Successful Execution**: Retry on status='success'
3. **Running Execution**: Retry on status='waiting'
4. **Deleted Workflow**: Retry execution of deleted workflow
5. **Modified Workflow**: Retry after workflow structure changed
6. **Concurrent Retries**: Multiple retry requests for same execution
7. **Execution Chain**: Retry an execution that was itself a retry
8. **Permission**: Retry execution from workflow user doesn't own
## Change Log
| Date | Version | Description | Author |
|------|---------|-------------|--------|
| 2025-12-26 | 1.0 | Story created for POST /executions/{id}/retry implementation | Sarah (PO) |
## Dev Agent Record
*This section will be populated by the development agent during implementation.*
### Agent Model Used
*To be filled by dev agent*
### Debug Log References
*To be filled by dev agent*
### Completion Notes List
*To be filled by dev agent*
### File List
*To be filled by dev agent*
## QA Results
*This section will be populated by QA agent after implementation and validation.*