microsoft/semantic-kernel · error · RuntimeError
The task ledger is not initialized. Planning needs to happen
Error message
The task ledger is not initialized. Planning needs to happen first.
What it means
replan() reads self.task_ledger to update facts and the plan. That ledger is only created inside plan(), so calling replan on a manager that has never planned leaves task_ledger as None and the method cannot proceed. The manager enforces the plan-then-replan lifecycle.
Source
Thrown at python/semantic_kernel/agents/orchestration/magentic.py:332
self.prompt_execution_settings,
)
assert plan is not None # nosec B101
self.task_ledger = _TaskLedger(facts=facts, plan=plan)
return await self._render_task_ledger(magentic_context)
@override
async def replan(self, magentic_context: MagenticContext) -> ChatMessageContent:
"""Replan the task.
Args:
magentic_context (MagenticContext): The context for the Magentic manager.
Returns:
ChatMessageContent: The updated task ledger.
"""
if self.task_ledger is None:
raise RuntimeError("The task ledger is not initialized. Planning needs to happen first.")
# 1. Update the facts
prompt_template = KernelPromptTemplate(
prompt_template_config=PromptTemplateConfig(template=self.task_ledger_facts_update_prompt)
)
magentic_context.chat_history.add_message(
ChatMessageContent(
role=AuthorRole.USER,
content=await prompt_template.render(
Kernel(),
KernelArguments(task=magentic_context.task.content, old_facts=self.task_ledger.facts.content),
),
)
)
facts = await self.chat_completion_service.get_chat_message_content(
magentic_context.chat_history,
self.prompt_execution_settings,
)View on GitHub (pinned to c028a0c7dc)
Solutions
- Call `await manager.plan(context)` first to initialize the task ledger before any replan.
- Drive the manager through MagenticOrchestration.invoke(), which calls plan/replan in the correct order automatically.
- If reusing the instance for a new task, reset by constructing a fresh StandardMagenticManager or re-running plan().
Example fix
// before manager = StandardMagenticManager(service) await manager.replan(context) # raises: ledger is None // after manager = StandardMagenticManager(service) await manager.plan(context) # initializes task ledger await manager.replan(context) # ok
Defensive patterns
Strategy: validation
Validate before calling
# Ensure plan ran before replan
if getattr(manager, "task_ledger", None) is None:
await manager.plan(context) # initialize ledger
await manager.replan(context) Type guard
def manager_has_plan(mgr) -> bool:
return getattr(mgr, "task_ledger", None) is not None Prevention
- Always call plan() before replan() on the same manager instance.
- Prefer MagenticOrchestration.invoke() which manages the plan/replan lifecycle.
- Construct a fresh StandardMagenticManager per independent task.
When it happens
Trigger: Calling `await manager.replan(context)` on a StandardMagenticManager instance whose `plan()` was never invoked (task_ledger is still its default None). Common when driving the manager manually instead of through MagenticOrchestration.
Common situations: Subclassing or scripting the manager directly and skipping the initial planning step. Reusing a manager instance for a new task without re-planning. Test code that exercises replan in isolation.
Related errors
- The Magentic manager is not started yet. Make sure to send a
- The initial state provided for step {this.Name} is not of th
- State has not been initialized
- Thread has been deleted; call `create()` to recreate it.
- Cannot create thread because it has already been deleted.
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/214ec7552c25a6e0.
Report an issue: GitHub.