Skip to content

Every one of the 24 flows fails its cold-boot re-bind with a validation error the log truncates to [ #653

Description

@os-zhuang

Found while measuring #640 on a fresh install; filed unassigned per Prime Directive #10 and deliberately not fixed there.

What happens

Every boot of objectstack dev --fresh emits 24 warnings — one per registered flow — from the automation service's kernel:ready re-bind:

WARN [Automation] cold-boot flow bind: failed to register campaign_enrollment: [
WARN [Automation] cold-boot flow bind: failed to register case_escalation: [
WARN [Automation] cold-boot flow bind: failed to register case_escalation_on_create: [
… 21 more, ending with …
WARN [Automation] cold-boot flow bind: failed to register task_due_reminder: [

That is all 24 flows in allFlows, not a subset — nothing is spared, including flows that were untouched for months.

Measured on 17.0.0-rc.1, pnpm dev --fresh, empty database, on main with no local edits.

Why the message is a bare [

syncFlowsFromProtocol in @objectstack/service-automation logs
`…failed to register ${def.name}: ${err.message}`, and the logger writes one
line per record. err.message here begins with [\n {\n "code": … — a Zod
issue array — so everything after the opening bracket is on the next lines and
never reaches the log. The result is 24 warnings a maintainer cannot act on:
they name the flow but not the problem.

So there are two defects stacked, and the second one is why the first has gone
unnoticed:

  1. every flow fails a schema validation on the re-bind path, and
  2. the warning is unreadable, so nobody knows what the validation says.

Why it is not (visibly) breaking anything

The re-bind is deliberately additive — the doc comment above it says so:

Bind flows from the protocol's flattened flow view at kernel:ready, so
record-triggered automations actually bind on a fresh start (#2560).
Additive by design … a transient empty/failed read at boot can't unbind the
flows the boot pull already registered.

The earlier boot pull registers the flows from the artifact, and those
registrations survive. Record-triggered automation demonstrably works: raising
crm_opportunity.amount to $310K on a fresh install opens the approval request
and routes it. So this is currently noise plus an unproven path, not an
outage.

That is exactly what makes it worth a look rather than a shrug: the path that
re-hydrates flows from stored metadata rejects 24 out of 24 flows, and the
only reason the app works is that a different path already registered them. Any
scenario that leans on the stored view alone — a metadata reload, a host that
boots from sys_metadata rather than the artifact — inherits a flow set of
zero, silently.

Repro

pnpm dev --fresh -p 41874 2>&1 | grep "cold-boot flow bind" | wc -l   # → 24

What is needed

  1. Log the whole err.message (or the Zod issues as structured data) so the
    warning names the field that fails. A truncated diagnostic is worse than
    none: it costs a boot to read and tells you nothing.
  2. Then find out what the flattened protocol view carries that FlowSchema
    rejects, and fix it at the producer — whether that is our metadata or the
    platform's flatten step. If it turns out to be platform-side, this belongs
    upstream in objectstack with the message from step 1 attached.

Related: #650 (decision node config.condition inert), #643 / #649 (flow
condition totality) — same subsystem, different layer.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingmetadataDeclarative metadata — schema, security posture, UI surfacespm:queueReady for the PM dispatch loopprio:p1Next in line once P0s clear

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions