{"record":{"id":"701757c72fe6a5ed","repo":"shareAI-lab/learn-claude-code","slug":"assignment-for-owner-is-no-longer-active","errorCode":null,"errorMessage":"Assignment for {owner} is no longer active","messagePattern":"Assignment for (.+?) is no longer active","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"s13_agent_teams/code.py","lineNumber":404,"sourceCode":"    path, error = _registered_worktree(task.worktree)\n    return (path or WORKDIR), error\n\n\ndef assignment_cwd(owner: str) -> Path:\n    with task_lock:\n        assignment = teammate_assignments.get(owner)\n        task = _owner_in_progress(owner)\n        if task and (not assignment or assignment.get(\"task_id\") != task.id):\n            cwd, error = task_worktree_cwd(task)\n            if error:\n                raise ValueError(error)\n            assignment = {\"task_id\": task.id, \"cwd\": cwd}\n            teammate_assignments[owner] = assignment\n        elif not assignment:\n            return WORKDIR\n        task = load_task(str(assignment[\"task_id\"]))\n        if task.status not in {\"in_progress\", \"completed\"} or task.owner != owner:\n            raise ValueError(f\"Assignment for {owner} is no longer active\")\n        cwd, error = task_worktree_cwd(task)\n        if error:\n            raise ValueError(error)\n        if cwd.resolve() != Path(assignment[\"cwd\"]).resolve():\n            raise ValueError(f\"Assignment cwd changed for task {task.id}\")\n        return cwd\n\n\ndef release_completed_assignment(owner: str) -> bool:\n    \"\"\"Release a completed cwd lease only at a model turn boundary.\"\"\"\n    with task_lock:\n        assignment = teammate_assignments.get(owner)\n        if not assignment:\n            return False\n        task = load_task(str(assignment[\"task_id\"]))\n        if task.status != \"completed\" or task.owner != owner:\n            return False\n        teammate_assignments.pop(owner, None)","sourceCodeStart":386,"sourceCodeEnd":422,"githubUrl":"https://github.com/shareAI-lab/learn-claude-code/blob/985456f4adea6f4df8fbad4112245dbd97444eae/s13_agent_teams/code.py#L386-L422","documentation":"While resolving an owner's working directory, the system loads the task recorded in the owner's assignment lease and requires it to still be owned by that owner with status 'in_progress' or 'completed'. If the task was reassigned, reset to 'pending', or otherwise mutated, the lease is stale and ValueError is raised rather than silently returning the wrong cwd.","triggerScenarios":"A teammate's in-progress task is reassigned to another agent or its status reset to 'pending' while its assignment lease still points at it; the task JSON is hand-edited; a test resets task state without clearing teammate_assignments.","commonSituations":"Rebalancing work between agents mid-run; manual intervention in .tasks/; restart flows that reload tasks but not assignment leases.","solutions":["When reassigning or resetting a task, also clear the previous owner's entry in teammate_assignments (call release_completed_assignment or drop the lease) in the same locked section.","Catch this ValueError in the owner loop and have the owner fall back to the main WORKDIR and re-claim work.","Avoid hand-editing task owner/status for assigned tasks."],"exampleFix":"# before (reassign without dropping lease)\ntask.owner = new_owner\nsave_task(task)  # old owner's next cwd_for() raises\n\n# after\nwith task_lock:\n    task.owner = new_owner\n    save_task(task)\n    teammate_assignments.pop(old_owner, None)","handlingStrategy":"fallback","validationCode":"def assignment_active(owner: str) -> bool:\n    with task_lock:\n        a = teammate_assignments.get(owner)\n        if not a:\n            return False\n        try:\n            t = load_task(str(a['task_id']))\n        except ValueError:\n            return False\n        return t.owner == owner and t.status in {'in_progress', 'completed'}","typeGuard":null,"tryCatchPattern":"try:\n    cwd = owner_cwd(owner)\nexcept ValueError as exc:\n    if 'no longer active' in str(exc):\n        with task_lock:\n            teammate_assignments.pop(owner, None)  # drop stale lease\n        cwd = WORKDIR  # fall back to main workspace this turn\n    else:\n        raise","preventionTips":["Always drop the owner's assignment lease when reassigning or resetting their task.","Mutate task owner/status only under task_lock.","Treat this error as a turn-boundary signal: release the lease and re-claim work."],"tags":["agent-coordination","stale-state","assignments","concurrency"],"backgroundTag":null,"analyzedSha":"985456f4adea6f4df8fbad4112245dbd97444eae","analyzedAt":"2026-08-14T22:02:26.028Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}