Schedule and manage recurring tasks with cron-based execution, drift prevention, and task persistence. Use this when agents need to run tasks periodically, set up automated jobs, or manage time-based workflows. Complexities: Cron parsing, drift correction, task persistence, error handling, retry logic, timezone handling.
Schedule recurring tasks with cron-based timing, automatic retry, and persistent storage.
Use this when you need to:
The task scheduling system uses cron-like scheduling with these components:
nanoclaw/src/task-scheduler.ts - Main scheduler implementationnanoclaw/src/db.ts - Task persistence layernanoclaw/src/ipc.ts - IPC communication for task resultsswarm-workspace/ipc/ - Task status and result files// Schedule a daily task at 9 AM
const task = await scheduleTask({
name: 'daily-report',
cronExpression: '0 9 * * *', // 9 AM every day
command: 'generate-report',
group: 'main',
timezone: 'America/New_York'
});
// Returns: { taskId: 'task_123', nextRun: '2026-03-17T09:00:00-04:00' }
// Schedule with retry on failure
const task = await scheduleTask({
name: 'fetch-data',
cronExpression: '0 */6 * * *', // Every 6 hours
command: 'fetch-external-data',
retryConfig: {
maxRetries: 3,
backoffMultiplier: 2, // Exponential backoff
initialDelayMs: 60000 // Start with 1 minute delay
}
});
// Schedule with execution timeout
const task = await scheduleTask({
name: 'long-running-task',
cronExpression: '0 0 * * 0', # Midnight every Sunday
command: 'weekly-backup',
timeoutMs: 3600000 // 1 hour timeout
});
┌───────────── minute (0 - 59)
│ ┌───────────── hour (0 - 23)
│ │ ┌───────────── day of month (1 - 31)
│ │ │ ┌───────────── month (1 - 12)
│ │ │ │ ┌───────────── day of week (0 - 6, 0 = Sunday)
│ │ │ │ │
* * * * *
Examples:
0 9 * * * - 9:00 AM every day*/15 * * * * - Every 15 minutes0 0 * * 0 - Midnight every Sunday0 9 * * 1-5 - 9:00 AM Monday through Friday0 0 1 * * - Midnight on the first day of every monthinterface TaskConfig {
name: string; // Unique task name
cronExpression: string; // Cron schedule
command: string; // Command to execute
group?: string; // Group context (default: 'main')
timezone?: string; // Timezone (default: UTC)
enabled?: boolean; // Enable/disable task (default: true)
timeoutMs?: number; // Execution timeout (default: 300000)
retryConfig?: {
maxRetries: number; // Maximum retry attempts (default: 0)
backoffMultiplier: number; // Exponential backoff multiplier
initialDelayMs: number; // Initial retry delay
};
metadata?: Record<string, any>; // Custom metadata
}
{
taskId: 'task_123',
name: 'daily-report',
cronExpression: '0 9 * * *',
nextRun: '2026-03-17T09:00:00-04:00',
lastRun: '2026-03-16T09:00:00-04:00',
status: 'scheduled', // scheduled, running, completed, failed
runCount: 42,
lastResult: {
success: true,
exitCode: 0,
durationMs: 5234,
output: 'Report generated successfully\n'
}
}
Common errors and solutions:
Tasks can accumulate delays over time (e.g., if a task takes 5 minutes to run but is scheduled every minute). The scheduler prevents drift by:
Example:
* * * * *Task not running:
# Check if scheduler is running
docker logs praxis-swarm | grep -i scheduler
# Verify task is enabled
sqlite3 nanoclaw/data.db "SELECT * FROM tasks WHERE name='daily-report'"
# Check next run time
sqlite3 nanoclaw/data.db "SELECT name, next_run, enabled FROM tasks"
Task failing repeatedly:
# View task execution history
sqlite3 nanoclaw/data.db "SELECT * FROM task_runs WHERE task_id='task_123' ORDER BY created_at DESC LIMIT 10"
# Check task logs
docker logs praxis-swarm | grep -i "task_123"
# View IPC error files
ls -la swarm-workspace/ipc/errors/
Schedule not working as expected:
# Test cron expression
node -e "console.log(new CronParser('0 9 * * *').next().toString())"
# Verify timezone setting
sqlite3 nanoclaw/data.db "SELECT name, timezone FROM tasks"
# Check system time
docker exec praxis-swarm date
Drift occurring:
# Check execution times
sqlite3 nanoclaw/data.db "SELECT created_at FROM task_runs WHERE task_id='task_123' ORDER BY created_at DESC LIMIT 20"
# Verify drift prevention is enabled
docker logs praxis-swarm | grep -i drift
After scheduling a task:
SELECT * FROM tasks WHERE name='your-task'SELECT name, next_run FROM tasksSELECT name, enabled FROM tasksSELECT * FROM task_runs ORDER BY created_at DESC LIMIT 1SELECT success, exit_code FROM task_runs// List all tasks
const tasks = await listTasks();
// Get specific task
const task = await getTask('task_123');
// Update task
await updateTask('task_123', { enabled: false });
// Delete task
await deleteTask('task_123');
// Run task immediately (ignore schedule)
await runTaskNow('task_123');
// Get task execution history
const history = await getTaskHistory('task_123', { limit: 10 });
Swarm uses task scheduling for: