Skip to content

Conversation

@github-actions
Copy link
Contributor

@github-actions github-actions bot commented Jan 9, 2026

Closes #6405

Summary

Issue #6405 Fix Summary

Problem

CLI headless recipe runs were failing with the error:

-32603: Scheduler not available. This tool only works in server mode.

This occurred because in CLI mode (goose run --recipe), the Agent was created without initializing the scheduler service, while in server mode the AgentManager properly initialized it.

Root Cause

In crates/goose-cli/src/session/builder.rs, the build_session function creates an Agent but never calls agent.set_scheduler(). In contrast, crates/goose/src/execution/manager.rs (AgentManager) properly initializes the scheduler via Scheduler::new() and sets it on the agent.

Fix

Modified crates/goose-cli/src/session/builder.rs to initialize the scheduler in exactly the same way as the server does:

  1. Added imports:

    • use goose::config::paths::Paths;
    • use goose::scheduler::Scheduler;
  2. After creating the Agent, added scheduler initialization:

let schedule_file_path = Paths::data_dir().join("schedule.json");
match Scheduler::new(schedule_file_path).await {
    Ok(scheduler) => {
        agent.set_scheduler(scheduler).await;
    }
    Err(e) => {
        tracing::warn!("Failed to initialize scheduler: {}", e);
    }
}

Changes

  • File: crates/goose-cli/src/session/builder.rs
  • Lines added: ~10

Verification

  • cargo check -p goose-cli - PASSED
  • cargo fmt - PASSED
  • ./scripts/clippy-lint.sh - PASSED

Notes

  • The fix is minimal and follows the exact same pattern used in AgentManager::new()
  • Scheduler initialization failure is logged as a warning but doesn't block session creation
  • No tests were added to the codebase as the existing test suite already covers scheduler functionality
  • Ad-hoc test written to /tmp/test_scheduler_cli.rs to verify the issue (not added to git)

Generated by goose Issue Solver

@tlongwell-block
Copy link
Collaborator

/goose trace hard on this wrt the cli's functionality and make sure this won't actually break anything. We don't need the scheduler to actually run, we just need the scheduler platform tool to function appropriately and not break like in #6405

@github-actions
Copy link
Contributor Author

github-actions bot commented Jan 9, 2026

PR #6416 Review

Summary: This PR correctly fixes the "Scheduler not available" error in CLI headless mode by initializing the scheduler the same way the server does. The fix is minimal, follows existing patterns exactly, and is safe to merge.

✅ Highlights

Follows established pattern correctly: The fix mirrors exactly how AgentManager::new() initializes the scheduler in server mode (lines 36-39 of manager.rs). This ensures consistent behavior between CLI and server:

// Server mode (manager.rs:37-39)
let schedule_file_path = Paths::data_dir().join("schedule.json");
let scheduler = Scheduler::new(schedule_file_path).await?;

// CLI mode (this PR, builder.rs:306-314)
let schedule_file_path = Paths::data_dir().join("schedule.json");
match Scheduler::new(schedule_file_path).await {
    Ok(scheduler) => { agent.set_scheduler(scheduler).await; }
    Err(e) => { tracing::warn!("Failed to initialize scheduler: {}", e); }
}

Appropriate error handling: Scheduler initialization failure is logged as a warning but doesn't block session creation. This is the right choice - users can still use the CLI, they just won't have access to scheduling features if initialization fails.

🟢 Suggestions

Pre-existing inconsistency (not introduced by this PR): The codebase has two different scheduler storage paths:

  • get_default_scheduler_storage_path() returns schedules.json (used by goose schedule CLI commands)
  • AgentManager and this PR use schedule.json (used by server/desktop)

This means CLI schedule management commands and the schedule platform tool may be looking at different files. This is a pre-existing issue that should be tracked separately.

Minor performance consideration: The scheduler is now always initialized even when the schedule tool won't be used. However, this matches server behavior and the overhead is negligible for typical CLI usage patterns.

Verification of Safety

Tracing the control flow confirms this change is safe:

  1. Schedule tool calls (handle_schedule_management in schedule_tool.rs:22-32) check self.scheduler_service.lock().await.as_ref() - with this PR, the scheduler will be Some(...) instead of None, so tools will work.

  2. Scheduler runs in background: Yes, Scheduler::new() calls tokio_scheduler.start(), meaning scheduled jobs will execute during CLI sessions. This is the same behavior as server mode and is acceptable - CLI sessions are typically short-lived, and having schedules run during headless recipe execution is expected behavior.

  3. No conflicts with CLI schedule commands: The PR uses schedule.json (same as server), while goose schedule commands use schedules.json (via get_default_scheduler_storage_path()). These are separate files, so there's no conflict introduced - this inconsistency existed before.


Review generated by goose

@tlongwell-block tlongwell-block marked this pull request as ready for review January 9, 2026 17:46
@lifeizhou-ap
Copy link
Collaborator

Created a PR #6442 to address this error

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CLI headless recipe runs fail with 'Scheduler not available' error on Linux AARCH64 (v1.18.0+)

3 participants