{"record":{"id":"72daf543f3a87dfa","repo":"affaan-m/ECC","slug":"template-template-name-requires-session-slots","errorCode":null,"errorMessage":"template {template_name} requires {} session slots but only {available_slots} available","messagePattern":"template (.+?) requires (.+?) session slots but only (.+?) available","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"ecc2/src/session/manager.rs","lineNumber":637,"sourceCode":"        .transpose()?;\n    let vars = build_template_variables(&repo_root, source_session.as_ref(), task, variables);\n    let template = cfg.resolve_orchestration_template(template_name, &vars)?;\n    let live_sessions = db\n        .list_sessions()?\n        .into_iter()\n        .filter(|session| {\n            matches!(\n                session.state,\n                SessionState::Pending\n                    | SessionState::Running\n                    | SessionState::Idle\n                    | SessionState::Stale\n            )\n        })\n        .count();\n    let available_slots = cfg.max_parallel_sessions.saturating_sub(live_sessions);\n    if template.steps.len() > available_slots {\n        anyhow::bail!(\n            \"template {template_name} requires {} session slots but only {available_slots} available\",\n            template.steps.len()\n        );\n    }\n\n    let default_profile = cfg\n        .default_agent_profile\n        .as_deref()\n        .map(|name| cfg.resolve_agent_profile(name))\n        .transpose()?;\n    let base_grouping = SessionGrouping {\n        project: Some(\n            source_session\n                .as_ref()\n                .map(|session| session.project.clone())\n                .unwrap_or_else(|| default_project_label(&repo_root)),\n        ),\n        task_group: Some(","sourceCodeStart":619,"sourceCodeEnd":655,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/ecc2/src/session/manager.rs#L619-L655","documentation":"When launching sessions from a template, the system counts live sessions (Pending, Running, Idle, Stale) and subtracts from max_parallel_sessions to compute available slots. If the template's step count exceeds the remaining slots, the operation bails. This prevents overcommitting parallel session capacity.","triggerScenarios":"Calling the template-launch path when template.steps.len() exceeds (cfg.max_parallel_sessions minus the count of sessions currently in Pending, Running, Idle, or Stale states).","commonSituations":"Running several concurrent agent sessions that fill capacity, then launching a multi-step template. Or setting max_parallel_sessions too low for the template size in config.","solutions":["Increase max_parallel_sessions in config to accommodate template step count plus any in-flight sessions","Stop or complete idle/stale sessions to free slots before launching the template","Reduce the number of steps in the template","Query the live session count before launching and compare against configured capacity"],"exampleFix":"// before\nlaunch_template(template, cfg).await?;\n\n// after\nlet live = sessions.iter()\n    .filter(|s| matches!(s.state, SessionState::Pending | SessionState::Running | SessionState::Idle | SessionState::Stale))\n    .count();\nlet available = cfg.max_parallel_sessions.saturating_sub(live);\nif template.steps.len() > available {\n    return Err(anyhow!(\"Not enough slots: need {}, have {}\", template.steps.len(), available));\n}\nlaunch_template(template, cfg).await?;","handlingStrategy":"validation","validationCode":"fn available_session_slots(db: &StateStore, cfg: &Config) -> Result<usize> {\n    let sessions = db.list_sessions()?;\n    let live = sessions.iter()\n        .filter(|s| matches!(s.state, SessionState::Pending | SessionState::Running | SessionState::Idle | SessionState::Stale))\n        .count();\n    Ok(cfg.max_parallel_sessions.saturating_sub(live))\n}\n\n// Before launching:\nlet available = available_session_slots(db, cfg)?;\nif template.steps.len() > available {\n    return Err(anyhow!(\"need {} slots, only {} available\", template.steps.len(), available));\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Track live session count in the caller and block template launches when capacity is insufficient","Set max_parallel_sessions generously enough to handle your largest template","Implement a queue that waits for slots to free up instead of failing immediately"],"tags":["capacity","sessions","templates","configuration"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}