Skip to content

run: --max-projects truncates list before filtering processed projects #21

@materemias

Description

@materemias

Bug

--max-projects N truncates the project list to the first N entries before checking if they were already processed today. This means if the first N projects are all processed, nothing runs — even if later projects in the config are eligible.

Root Cause

In cmd/nightshift/commands/run.go lines 198-199:

if projectPath == "" && maxProjects > 0 && len(projects) > maxProjects {
    projects = projects[:maxProjects]
}

This slicing happens before buildPreflight() (line ~388) which checks WasProcessedToday(). So with --max-projects 1 and 5 configured projects, only projects[0] is ever considered.

Impact

With the default --max-projects 1 and the systemd timer firing every 30 minutes:

  • First tick: processes project[0] (e.g., qtdashboard)
  • All subsequent ticks: project[0] is "already processed today", list is truncated to just project[0], nothing runs
  • Projects 2-5 never get processed

This defeats the intended design where each timer tick would process the next unprocessed project.

Expected Behavior

--max-projects N should mean "process up to N eligible projects", not "only consider the first N projects in config order". The processed-today filter should run before the limit is applied.

Suggested Fix

Move the truncation after the processed-today filtering in buildPreflight(), or change the truncation to skip already-processed projects:

// Filter out processed projects first, then apply limit
var eligible []string
for _, p := range projects {
    if !state.WasProcessedToday(p) {
        eligible = append(eligible, p)
    }
}
if maxProjects > 0 && len(eligible) > maxProjects {
    eligible = eligible[:maxProjects]
}

Reproduction

  1. Configure 5 projects in config.yaml
  2. Run nightshift run --max-projects 1 — processes project 1
  3. Run nightshift run --max-projects 1 again — "nothing ran" (all skipped)
  4. Run nightshift run --max-projects 5 — processes projects 2-5

Workaround

Use --max-projects 5 (or higher) to include all projects in the candidate list, relying on the budget system to naturally limit how many actually run.

Environment

  • nightshift v0.3.2
  • Related: systemd timer fires every 30m with default --max-projects 1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions