runtime.mode: functions in ohmyhost.yaml, keep build.install and export a Worker module from src/ohmyhost/worker.ts:
fetch answers every request of the environment. The module receives the same bindings as a framework app: the application database, files, mail, runtime secrets and the declared egress origins. There is no build.command and no build.output; ohmyhost init --dry-run --json reports a missing module as a blocker.
Declare schedules
scheduled in the default export of src/ohmyhost/worker.ts; a Vite app keeps it in the default export of its companion src/ohmyhost/companion.ts. Named exports are never invoked. Init blocks a module without a default export (worker_module_default_export_required) and a declaration without the handler (scheduled_handler_required).
The platform bundles src/ohmyhost/worker.ts on its own, outside the framework build. tsconfig paths resolve; Vite-only aliases, framework virtual modules and modules that declare TanStack Start server functions or Next.js route handlers do not. Import plain application modules and the generated runtime clients, and keep framework entry code out of the Worker module. A script the runtime cannot start fails the deployment terminally; operation get reports error.code: runtime_candidate_rejected.
How a run executes
Every minute the platform starts one run per declared cron that is due. The handler receivescontroller.cron, controller.scheduledTime and controller.noRetry() together with the environment bindings. A run may take up to 120 seconds. A thrown error or a platform failure is retried in the following minutes up to three attempts; calling controller.noRetry() before throwing stops the retries. Promotion and rollback switch the crons together with the deployment, and deleting the project removes them.
Observe runs
Scheduled runs are not deployment log events. Read them per environment, newest first:function_runs_list and GET /v1/projects/{project_id}/environments/{environment_id}/function-runs return the same list. Each run carries its cron, the scheduled UTC minute, state (due, running, retry, succeeded, failed), the attempt, the status the handler returned (204 for a completed handler, 422 when it called controller.noRetry() and threw, 500 for a thrown error) and its start and finish times. A declared cron with no run for a past due minute means the environment had no active deployment with that cron at the time.