Skip to content

bug: gateway cron registration (syncWorkflowToCron) is implemented but never called — workflows only scheduled via in-process node-cron #118

Description

@p11n-com

Summary

syncWorkflowToCron in SYSTEM/dashboard/server/lib/workflows.ts implements full openclaw gateway cron registration — it builds per-agent cron jobs, resolves agent models, and calls openclaw cron add. However, it is never imported or called anywhere in the codebase. The PUT route (and all other routes that modify workflows) call syncAllWorkflows() from scheduler.ts instead, which only manages in-process node-cron jobs. Gateway cron registration is dead code.

As a result, workflow schedules only persist in-process. They do not survive a container restart. This affects every ClawMax install — it is not a degraded-state failure, it is a wiring gap that was never closed.

Applicability

Universal — affects every ClawMax install with scheduled workflows. The issue is not conditional on gateway state, auth configuration, or error paths; the gateway cron path is simply never reached.

Steps to Reproduce

  1. Open ClawMax, create a workflow with a cron schedule, save it.
  2. Restart the container.
  3. The workflow fires only if startScheduler() re-reads the markdown file and re-schedules via node-cron. The openclaw gateway has no record of the job.
  4. Verify: grep -rn "syncWorkflowToCron" SYSTEM/dashboard/ returns only the definition in workflows.ts — no callers.

Root Cause

File: SYSTEM/dashboard/server/lib/workflows.ts (lines 349–420)

// Fully implemented, exported — but zero callers
export function syncWorkflowToCron(
  workflow: Workflow,
  participants: string[]
): { ok: boolean; cronJobId?: string; error?: string } {
  // builds openclaw cron add args, calls execSync(...)
}

File: SYSTEM/dashboard/server/routes/workflows.ts — PUT handler

import { syncAllWorkflows } from '../lib/scheduler'  // ← only this is imported
// syncWorkflowToCron is never imported or called
// ...
syncAllWorkflows()  // ← in-process node-cron only
res.json({ success: true, workflow: updatedWorkflow })

The gateway cron wiring was written but never plumbed into the route layer.

Proposed Fix

Import and call syncWorkflowToCron in the PUT (and POST/DELETE) handlers, surface failures as a non-blocking warning:

// routes/workflows.ts — after saving the workflow
import { syncWorkflowToCron } from '../lib/workflows'
import { syncAllWorkflows } from '../lib/scheduler'

const participantIds = resolveParticipants(updatedWorkflow)
const cronResult = syncWorkflowToCron(updatedWorkflow, participantIds)
syncAllWorkflows()  // keep in-process scheduler in sync too

res.json({
  success: true,
  workflow: updatedWorkflow,
  warnings: cronResult.ok
    ? []
    : [`Gateway cron registration failed: ${cronResult.error}. Schedule will run via in-process scheduler only.`],
})

The client can surface a yellow banner when warnings.length > 0, giving the user actionable information without blocking the save.

Affected Files

File Change
SYSTEM/dashboard/server/routes/workflows.ts Import syncWorkflowToCron; call it in PUT/POST/DELETE handlers; surface warnings in response
SYSTEM/dashboard/client/src/pages/Workflows.tsx (or equivalent) Display non-blocking warning banner when response includes warnings

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinghigh-priorityCritical — fix this sprint

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions