Skip to content

release: to prod#1304

Merged
joelorzet merged 20 commits into
prodfrom
staging
May 20, 2026
Merged

release: to prod#1304
joelorzet merged 20 commits into
prodfrom
staging

Conversation

@joelorzet

Copy link
Copy Markdown

No description provided.

nickkounz and others added 16 commits May 19, 2026 11:43
…P-576)

The executor's catch handler unconditionally overwrote
`outputs[sanitizedNodeId] = { data: null }` after a step threw, even when
the step's first attempt had already populated the entry with a successful
object. Under heavy fan-in the SDK can lose the post-step `step_completed`
event and replay the step (the same race covered by the spurious-max-retries
reconciliation just above); the replay then throws with a shape that doesn't
match the reconciliation regexes, falls through to the nullify path, and
discards the surviving success.

Downstream resolvers (`processCodeTemplates` / `replaceConfigTemplate`)
then see `output.data === null`, record `no-data`, and in strict mode raise
`TemplateResolutionError: Node "X" produced no data.` Observed in prod on a
5-node forked bridge-optimizer-usdc workflow whose Bungee leg consistently
errored at the convergence combine step.

Extract the catch-time write into `recordCatchOutput(outputs, sanitizedId,
label)`: preserve the prior entry if `data` is neither null nor undefined,
otherwise write `{ label, data: null }`. The downstream-safe null-fallback
contract is preserved for genuinely-failed nodes.

Also remove four diagnostic console.logs added during the investigation.

Tests: `tests/unit/executor-catch-output.test.ts` covers the four
`recordCatchOutput` cases (empty / undefined / null / success), the
soft-fail wrapper case, and a resolver sentinel asserting that
`data === null` still produces the strict-mode "no-data" reason so the fix
remains load-bearing.
Adds a CLAUDE.md rule under "AI Agents Code Policy" that Linear ticket IDs
(e.g. KEEP-XXX) must not appear in code comments, PR titles, or PR
descriptions. Linear's GitHub integration cross-links via the branch name,
so the ticket ID does not need to be repeated in the artifact itself.
Commit messages and internal docs under .planning/ and specs/ are still
allowed to reference Linear IDs.
Adds a plural-form alias that re-exports the existing singular handler.
Both /api/workflow/{id}/execute and /api/workflows/{id}/execute now work,
removing the path-inconsistency 404 trap REST clients hit when guessing the
documented plural form. Docs updated to show the plural as canonical.
Drizzle returns totalSteps and completedSteps as TEXT and JSON.stringify
preserves that, so GET /api/workflows/{id}/executions emits
completedSteps:'4' and totalSteps:null. Type-checked SDK clients (Pydantic,
Zod, Go) either fail validation or coerce silently.

Coerce both fields to number|null in the route handler before serializing.
Non-numeric strings fall through as null rather than NaN. Update the
api-client and workflow-runs component types to match the new shape.

Column type stays TEXT for now; a later migration to integer can drop the
coercion layer.
…cute endpoints

The execute endpoints required a stringified chainId in 'network' but the
docs used chain names. The crucible hackathon evidence: API rejected
'sepolia'/'ethereum'/'base' even though those names are widely-used aliases.

Changes:
- /api/execute/[...slug] now resolves the chain input (chainId or network,
  numeric or string or known name) before looking up contract.addresses.
  Previously 'sepolia' failed the lookup outright; now it normalizes to
  '11155111' first.
- transfer, contract-call, and check-and-execute routes accept chainId as
  the canonical field with network retained as a deprecated alias.
- Validators check 'one of chainId | network is present' instead of
  hard-requiring network.
- MCP schemas tip rewritten to declare chainId canonical, with the alias
  set documented.
- docs/api/chains.md gains a Chain Identifiers section with the full alias
  table and clarifies that {chainId} in /api/chains/{chainId}/abi is the
  numeric chain ID.

Not in this PR (follow-ups):
- Renaming 'network' to 'chainId' in every plugin step's configFields and
  the corresponding saved-workflow data migration.

Two new unit-test files cover validator behavior and the route-level chain
name resolution.
The kh CLI advertises a global --org <slug> flag, wires it correctly to
send the value as X-Organization-Id on every request, but the backend was
ignoring the header for session auth and silently using the session's
active organization instead. Empirical check: kh --org joel-lADwbK
project list and kh --org fafa project list both returned the same active
org's projects. The flag was a no-op on every command, not just workflow
create as the ticket described.

Now: for session-auth callers, X-Organization-Id (accepting either an
org id or slug) names the effective organization. The handler validates
the session user is a member of the target org and rejects 404 / 403
otherwise; absent header still falls back to the session's active org so
existing clients are unaffected.

API-key auth keeps hard org-scoping (the dual-auth-context test that
pins this stays green). OAuth tokens keep token-bound scoping.

Now scripted use (CI bulk-provisioning into a target org) works without
mutating the user's session default via kh org switch.
…e-alias-route

fix(api): KEEP-477 add plural /api/workflows/[id]/execute alias
…se-step-counts

fix(api): KEEP-481 coerce execution step counts to number|null
…al-field

fix(api): KEEP-490 accept chainId as canonical chain input on execute endpoints
Collapse the org-lookup and membership-check into a single inner-joined
query. When the row is missing, return the same 404 "Organization not
found" whether the org does not exist or the caller is not a member, so
any authenticated session can no longer enumerate org ids and slugs by
toggling the header.
…tion-id-for-session-auth

fix(api): KEEP-563 honor X-Organization-Id header for session auth
Introduce an 'unlisted' visibility between private and public so
users can share a workflow via URL without publishing it on the
Hub. Reshapes the share overlay around a general-access combobox
(Private / Anyone with the link / Public), updates the read-only
callout shown to non-owner viewers to point at the 'Use template'
button, and gates the billing announcement banner to logged-in
users so the hub padding stays correct.
…olver

fix(executor): preserve prior in-memory success in catch handler
…aring

feat: add link-only workflow sharing
@joelorzet joelorzet requested review from a team, OleksandrUA, eskp and suisuss and removed request for a team May 19, 2026 21:12
joelorzet added 2 commits May 19, 2026 19:43
…ne bucket

Several user-config error families were defaulting to workflow_engine + system
because no pattern matched them. They now classify as user errors, which keeps
the SLI engine-error alert focused on real engine faults.

Added rules:
  - HTTP <status>: ... (webhook/safe/discord etc. non-2xx from user endpoint)
  - HTTP request failed: ... (fetch failures: ECONNRESET, ENOTFOUND, timeout)
  - Token approval/transfer failed, Transaction failed (transaction reverts)
  - Invalid Ethereum address
  - Function '<name>' not found in ABI
  - DATABASE_URL is not configured
  - Failed to initialize organization wallet: Para session expired
    (precedes the generic wallet-init system rule)
…-engine-bucket

fix(errors): reclassify user-config failures out of the workflow_engine bucket
Resolves CONFLICTING state on staging->prod release PR #1304.

The two conflicting files (lib/errors/classify.ts and its test) had
staging additions that are strict supersets of prod's version (newer
classifier rules for token transfer/approval, ABI lookup, HTTP status,
DATABASE_URL, Para session). Taking staging's version preserves those
rules; the merge contributes no other tree changes since prod's
hotfixes had already landed on staging via independent paths.
…-pr1304

chore: merge prod into staging to clear PR #1304 conflicts
@joelorzet joelorzet merged commit 10ed185 into prod May 20, 2026
34 checks passed
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.

4 participants