Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion apps/server/src/services/auto-mode-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,12 @@ import type {
ThinkingLevel,
PlanningMode,
} from '@automaker/types';
import { DEFAULT_PHASE_MODELS, isClaudeModel, stripProviderPrefix } from '@automaker/types';
import {
DEFAULT_GLOBAL_SETTINGS,
DEFAULT_PHASE_MODELS,
isClaudeModel,
stripProviderPrefix,
} from '@automaker/types';
import {
buildPromptWithImages,
classifyError,
Expand Down Expand Up @@ -495,6 +500,21 @@ export class AutoModeService {
throw new Error('already running');
}

// Check global concurrency limit for manual executions
// (Auto-mode has its own check in the auto-loop, so skip for isAutoMode)
if (!isAutoMode) {
const globalSettings = await this.settingsService?.getGlobalSettings();
const maxConcurrency =
this.config?.maxConcurrency ??
globalSettings?.maxConcurrency ??
DEFAULT_GLOBAL_SETTINGS.maxConcurrency;
if (this.runningFeatures.size >= maxConcurrency) {
throw new Error(
`Cannot start: ${this.runningFeatures.size}/${maxConcurrency} agents already running`
);
}
Comment on lines 500 to 506
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, verify the file exists and examine its key sections
git ls-files | grep -i auto-mode-service

Repository: AutoMaker-Org/automaker

Length of output: 314


🏁 Script executed:

# Search for maxConcurrency and config-related patterns
rg -n --type=ts 'maxConcurrency' -B 2 -A 2

Repository: AutoMaker-Org/automaker

Length of output: 43754


🏁 Script executed:

# Search for this.config assignments and references
rg -n --type=ts 'this\.config\s*=' -B 1 -A 2

Repository: AutoMaker-Org/automaker

Length of output: 1654


🏁 Script executed:

# Look for AutoModeService class definition and constructor
rg -n --type=ts 'class AutoModeService|constructor\s*\(' -A 5 apps/server/src/services/auto-mode-service.ts

Repository: AutoMaker-Org/automaker

Length of output: 536


🏁 Script executed:

# Check the imports and config types
head -30 apps/server/src/services/auto-mode-service.ts

Repository: AutoMaker-Org/automaker

Length of output: 902


🏁 Script executed:

# Search for executeFeature calls to understand manual execution paths
rg -n 'executeFeature' --type=ts -B 2 -A 1 apps/server/src/

Repository: AutoMaker-Org/automaker

Length of output: 3679


🏁 Script executed:

# Check the SettingsService to see how maxConcurrency is accessed
rg -n 'settingsService' --type=ts apps/server/src/services/auto-mode-service.ts | head -20

Repository: AutoMaker-Org/automaker

Length of output: 1491


🏁 Script executed:

# Get the full executeFeature method signature and context
sed -n '480,530p' apps/server/src/services/auto-mode-service.ts

Repository: AutoMaker-Org/automaker

Length of output: 1663


🏁 Script executed:

# Check if this.config is initialized anywhere else besides startAutoLoop
rg -n 'this\.config\s*=' apps/server/src/services/auto-mode-service.ts

Repository: AutoMaker-Org/automaker

Length of output: 90


🏁 Script executed:

# Verify SettingsService has getGlobalSettings method
rg -n 'getGlobalSettings' --type=ts apps/server/src/services/settings-service.ts | head -5

Repository: AutoMaker-Org/automaker

Length of output: 341


🏁 Script executed:

# Check the full route file to confirm manual execution path
cat apps/server/src/routes/auto-mode/routes/run-feature.ts

Repository: AutoMaker-Org/automaker

Length of output: 1611


Manual executions ignore user-configured maxConcurrency; use settings instead.

When executeFeature is called manually (before auto-mode starts or via the run-feature route), this.config is undefined because it's only initialized in startAutoLoop. This causes the check at line 500–506 to default to 3, bypassing any user-configured limit from GlobalSettings.

The SettingsService is injected into AutoModeService (constructor line 279–281) and has a getGlobalSettings() method that returns the configured maxConcurrency. Use it for manual executions: retrieve maxConcurrency from settingsService.getGlobalSettings() when isAutoMode is false.

🤖 Prompt for AI Agents
In `@apps/server/src/services/auto-mode-service.ts` around lines 500 - 506, When
handling manual executions in executeFeature (where isAutoMode is false) the
code falls back to this.config which is only set by startAutoLoop; instead fetch
maxConcurrency from the injected SettingsService by calling
settingsService.getGlobalSettings() and reading its maxConcurrency when
this.config is undefined or isAutoMode is false, then use that value for the
runningFeatures.size check (preserve the existing error message and logic).
Update the branch around isAutoMode in executeFeature to prefer
this.config?.maxConcurrency when set, otherwise use
settingsService.getGlobalSettings().maxConcurrency, and ensure the existing
throw still triggers when runningFeatures.size >= resolved maxConcurrency.

}

// Add to running features immediately to prevent race conditions
const abortController = new AbortController();
const tempRunningFeature: RunningFeature = {
Expand Down
Loading