Skip to content

fix(workflow-executor): tolerate non-primitive field types in collection schema#1756

Open
ShohanRahman wants to merge 1 commit into
mainfrom
fix/workflow-executor-collection-schema-nonprimitive-field-types
Open

fix(workflow-executor): tolerate non-primitive field types in collection schema#1756
ShohanRahman wants to merge 1 commit into
mainfrom
fix/workflow-executor-collection-schema-nonprimitive-field-types

Conversation

@ShohanRahman

@ShohanRahman ShohanRahman commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Why

A customer running migrated workflows hit Internal validation error occurred while preparing the step (DomainValidationError) on their Get Data step. This message is DomainValidationError's user-facing text, thrown when CollectionSchemaSchema.parse() fails inside getCollectionSchema (forest-server-workflow-port.ts:197,209).

The executor's ColumnTypeSchema only accepts primitive/tuple/record/composite types. Two shapes in a forest-rails apimap fail it:

  • Hand-authored smart-field type strings not in PRIMITIVE_TYPES (e.g. DateTime) — rejected by z.enum(PRIMITIVE_TYPES).
  • [null] array-column types (columns the liana can't map) — the field's top-level type is already .nullable(), but the tuple branch z.tuple([ColumnTypeSchema]) has a non-nullable inner element, so [null] fails.

A single unmodelable field type failed the entire collection schema and blocked the run.

Note: this is a different bug from #1753 (which fixes null title/prompt/aiConfigName on step definitions). The customer's reported symptom traces to collection-schema validation, not step validation.

What

  • Add .catch(null) on FieldSchemaSchema.type so an unparseable type normalizes to null instead of throwing — the whole collection schema keeps parsing.
  • This is safe and consistent with the schema's documented "resilient to orchestrator drift" design (it already strips unknown keys). Consumers already guard on a null type — e.g. update-record-step-executor.ts:315 filters f.type != null.
  • Tests: non-primitive type string and [null] normalize to null; primitive/null/absent types are unchanged; a mixed collection parses instead of being rejected.

Test plan

  • yarn workspace @forestadmin/workflow-executor test -- test/types/collection.test.ts — 6/6 pass
  • Re-ran collection-schema consumers (forest-server-workflow-port, schema-resolver, schema-cache, update-record-step-executor) — 155/155 pass
  • Lint clean

🤖 Generated with Claude Code

Note

Tolerate non-primitive field types in FieldSchemaSchema collection parsing

Adds .catch(null) to the type field in FieldSchemaSchema so unparseable ColumnTypeSchema values (e.g. smart-field type strings or array-column [null]) resolve to null instead of failing validation. Explicit null stays null and missing type stays undefined. New Jest tests in collection.test.ts cover all these cases.

Macroscope summarized 54a2705.

…ion schema

forest-rails apimaps carry field types the executor's ColumnType contract
can't model — hand-authored smart-field type strings, and `[null]` from array
columns the liana fails to map. These made CollectionSchemaSchema.parse throw
a ZodError in getCollectionSchema, surfaced to the customer as a
DomainValidationError ("Internal validation error occurred while preparing the
step") that blocked their Get Data steps.

Add `.catch(null)` on the field `type` so an unparseable type normalizes to
null instead of failing the whole collection schema. Consumers already guard
on a null type (e.g. update-record filters `f.type != null`), consistent with
this schema's resilient-to-orchestrator-drift design.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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