ScheduleHandler routes never mounted in cmd/server/main.go — schedule CRUD API returns 404 in prod #1692

Closed
opened 2026-05-22 23:34:12 +00:00 by hongming · 1 comment
Owner

Bug

workspace-server/internal/handlers/schedules.go declares a full ScheduleHandler with List / Create / Update / Delete / RunNow / History methods. But the handler is never instantiated in workspace-server/cmd/server/main.goNewScheduleHandler() has zero callers.

Consequence:

  • GET / POST /workspaces/:id/schedules returns 404 in prod
  • The Canvas Schedule tab + any external scheduler-create flow is broken
  • The scheduler background loop (cronSched.Start) DOES run + DOES fire scheduled prompts (verified — it polls workspace_schedules table directly), but there is no public way to CREATE a schedule beyond direct SQL

Verified 2026-05-22 23:14Z:

  • POST agents-team.moleculesai.app/workspaces/deedcb61-.../schedules → 404
  • POST api.moleculesai.app/cp/admin/workspaces/.../schedules → 404
  • GET api.moleculesai.app/cp/admin/schedules → 404
  • grep -n NewScheduleHandler workspace-server/cmd/server/main.go → 0 matches

Fix

5-line patch in workspace-server/cmd/server/main.go, alongside existing handler mounting:

sh := handlers.NewScheduleHandler()
engine.GET("/workspaces/:id/schedules", sh.List)
engine.POST("/workspaces/:id/schedules", sh.Create)
engine.PATCH("/workspaces/:id/schedules/:sid", sh.Update)
engine.DELETE("/workspaces/:id/schedules/:sid", sh.Delete)
engine.POST("/workspaces/:id/schedules/:sid/run", sh.RunNow)
engine.GET("/workspaces/:id/schedules/:sid/history", sh.History)

Plus the existing requireWorkspaceToken / CanCommunicate auth middleware applied to the group, matching the patterns used for other workspace-scoped CRUD handlers.

Why it matters

  • Blocks the PM autonomous-cron SOP (Kimi/MiniMax 24/7 dispatch — see feedback_kimi_minimax_default_dispatch_2026_05_22)
  • Blocks any Canvas-side schedule management UX
  • The scheduler infrastructure (cron expr parse, fire timing, A2A dispatch, history, phantom sweep, native-scheduler-skip) is ALL there and working — only the HTTP face is missing

Acceptance

  • 6 routes registered + auth-gated
  • Smoke test: curl -X POST -H Authorization: Bearer <ws-token> /workspaces/:id/schedules -d ... → 201
  • E2E: create a schedule via API, verify next_run_at advances + cron fires per workspace_schedules.run_count

Owner

TBD. Estimated ~2h including tests.

## Bug `workspace-server/internal/handlers/schedules.go` declares a full `ScheduleHandler` with `List` / `Create` / `Update` / `Delete` / `RunNow` / `History` methods. But the handler is **never instantiated** in `workspace-server/cmd/server/main.go` — `NewScheduleHandler()` has zero callers. Consequence: - `GET / POST /workspaces/:id/schedules` returns **404 in prod** - The Canvas Schedule tab + any external scheduler-create flow is broken - The scheduler background loop (`cronSched.Start`) DOES run + DOES fire scheduled prompts (verified — it polls `workspace_schedules` table directly), but there is no public way to CREATE a schedule beyond direct SQL Verified 2026-05-22 23:14Z: - `POST agents-team.moleculesai.app/workspaces/deedcb61-.../schedules` → 404 - `POST api.moleculesai.app/cp/admin/workspaces/.../schedules` → 404 - `GET api.moleculesai.app/cp/admin/schedules` → 404 - `grep -n NewScheduleHandler workspace-server/cmd/server/main.go` → 0 matches ## Fix 5-line patch in `workspace-server/cmd/server/main.go`, alongside existing handler mounting: ```go sh := handlers.NewScheduleHandler() engine.GET("/workspaces/:id/schedules", sh.List) engine.POST("/workspaces/:id/schedules", sh.Create) engine.PATCH("/workspaces/:id/schedules/:sid", sh.Update) engine.DELETE("/workspaces/:id/schedules/:sid", sh.Delete) engine.POST("/workspaces/:id/schedules/:sid/run", sh.RunNow) engine.GET("/workspaces/:id/schedules/:sid/history", sh.History) ``` Plus the existing `requireWorkspaceToken` / `CanCommunicate` auth middleware applied to the group, matching the patterns used for other workspace-scoped CRUD handlers. ## Why it matters - Blocks the PM autonomous-cron SOP (Kimi/MiniMax 24/7 dispatch — see `feedback_kimi_minimax_default_dispatch_2026_05_22`) - Blocks any Canvas-side schedule management UX - The scheduler infrastructure (cron expr parse, fire timing, A2A dispatch, history, phantom sweep, native-scheduler-skip) is ALL there and working — only the HTTP face is missing ## Acceptance - 6 routes registered + auth-gated - Smoke test: `curl -X POST -H Authorization: Bearer <ws-token> /workspaces/:id/schedules -d ...` → 201 - E2E: create a schedule via API, verify `next_run_at` advances + cron fires per `workspace_schedules.run_count` ## Owner TBD. Estimated ~2h including tests.
Author
Owner

Closing — incorrect diagnosis. Schedule routes ARE mounted in workspace-server/internal/router/router.go (lines 374-385 of origin/main, the schedh := handlers.NewScheduleHandler() block under wsAuth). My grep on main.go missed this because the wiring lives in router.go, not main.go.

If PM is still 404-ing on schedule endpoints, the real gap is somewhere else — needs a fresh investigation:

  • Does the agent runtime SDK expose a set_schedule MCP tool that calls POST /workspaces/:id/schedules?
  • Is the Canvas Schedule tab using the correct WorkspaceAuth bearer + URL shape?
  • Is the Temporal cron worker actually fired up in this deployment?

Reopening once I have the actual broken layer identified.

Closing — incorrect diagnosis. Schedule routes ARE mounted in `workspace-server/internal/router/router.go` (lines 374-385 of origin/main, the `schedh := handlers.NewScheduleHandler()` block under `wsAuth`). My grep on main.go missed this because the wiring lives in router.go, not main.go. If PM is still 404-ing on schedule endpoints, the real gap is somewhere else — needs a fresh investigation: - Does the agent runtime SDK expose a `set_schedule` MCP tool that calls `POST /workspaces/:id/schedules`? - Is the Canvas Schedule tab using the correct WorkspaceAuth bearer + URL shape? - Is the Temporal cron worker actually fired up in this deployment? Reopening once I have the actual broken layer identified.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: molecule-ai/molecule-core#1692