Two related improvements to error handling and data safety
1. Conditional retry based on error type (extends #48)
Problem: The current retry mechanism treats all failures identically. There's no way to distinguish transient errors (429 rate limit, 502 gateway timeout, network flake) from permanent errors (401 auth failure, 403 forbidden, 404 not found). Every flow uses the same retries: 2, retryDelayMs: 1000 because there's no conditional logic.
This causes two problems:
- Wasting time retrying permanent failures (e.g., retrying a 401 won't fix auth)
- Not retrying enough for transient failures (e.g., a 429 needs backoff, not fixed 1s delay)
The Perplexity proxy bypass (#23) exists partly because the retry strategy can't detect 502s and back off.
Proposed solution:
{
"onError": {
"strategy": "retry",
"retries": 3,
"backoff": {
"type": "exponential",
"initialDelayMs": 1000,
"multiplier": 2,
"maxDelayMs": 30000
},
"retryOn": [429, 502, 503, "ETIMEDOUT", "ECONNRESET"],
"failFastOn": [401, 403, 404]
}
}
When a step fails:
- If the error matches
failFastOn → immediately fail (no retry)
- If the error matches
retryOn → retry with backoff
- If neither matches → fall back to current behavior
Impact: 75 flows have error handling. Conditional retry would eliminate direct-curl bypasses for long-running APIs and reduce wasted time on permanent failures.
2. Handlebars context-aware escaping (extends #41)
Problem: Handlebars has one escaping mode, but interpolated values land in 4 different contexts: shell commands, JSON payloads, URLs, and markdown/HTML. A company name like O'Brien & Co. will:
- Break shell commands (unescaped quote)
- Break JSON (unescaped quote)
- Break URLs (unescaped ampersand)
- Break HTML (unescaped ampersand)
We run a multi-layer content sanitization step as a post-hoc defense, but prevention would be cheaper.
Proposed solution — pipe-based escaping in Handlebars:
{{ companyName | json }} → JSON.stringify escaping
{{ companyName | shell }} → shell-safe escaping (quotes, special chars)
{{ companyName | url }} → encodeURIComponent
{{ companyName | md }} → markdown-safe (escape brackets, pipes)
{{ companyName | html }} → HTML entity escaping
Impact: Reduces reliance on defensive post-processing. Prevents a class of injection bugs at the template level. Affects 60+ flows that interpolate user-provided data.
Relationship to existing issues
Two related improvements to error handling and data safety
1. Conditional retry based on error type (extends #48)
Problem: The current retry mechanism treats all failures identically. There's no way to distinguish transient errors (429 rate limit, 502 gateway timeout, network flake) from permanent errors (401 auth failure, 403 forbidden, 404 not found). Every flow uses the same
retries: 2, retryDelayMs: 1000because there's no conditional logic.This causes two problems:
The Perplexity proxy bypass (#23) exists partly because the retry strategy can't detect 502s and back off.
Proposed solution:
{ "onError": { "strategy": "retry", "retries": 3, "backoff": { "type": "exponential", "initialDelayMs": 1000, "multiplier": 2, "maxDelayMs": 30000 }, "retryOn": [429, 502, 503, "ETIMEDOUT", "ECONNRESET"], "failFastOn": [401, 403, 404] } }When a step fails:
failFastOn→ immediately fail (no retry)retryOn→ retry with backoffImpact: 75 flows have error handling. Conditional retry would eliminate direct-curl bypasses for long-running APIs and reduce wasted time on permanent failures.
2. Handlebars context-aware escaping (extends #41)
Problem: Handlebars has one escaping mode, but interpolated values land in 4 different contexts: shell commands, JSON payloads, URLs, and markdown/HTML. A company name like
O'Brien & Co.will:We run a multi-layer content sanitization step as a post-hoc defense, but prevention would be cheaper.
Proposed solution — pipe-based escaping in Handlebars:
Impact: Reduces reliance on defensive post-processing. Prevents a class of injection bugs at the template level. Affects 60+ flows that interpolate user-provided data.
Relationship to existing issues