# CompanyOS keeps Routines linked to their Products

> Agno's PATCH /company/products/{id} route keeps a Product's routine_ids when you edit its metadata, and SchedulerTools answers a delete, enable or disable on a Company Routine with a company_routine error.

- Published: 2026-10-20
- Author: Yash Pratap Solanky
- Categories: Changelog
- Canonical: https://www.agno.com/blog/companyos-keeps-routines-linked-to-their-products
- Markdown: https://www.agno.com/blog/companyos-keeps-routines-linked-to-their-products.md

Agno's `CompanyManager.update` now copies a Product's stored Routine ids into the new `metadata` inside the update transaction, under the same write lock that links a new Routine, and drops any `routine_ids` the caller sends. That `routine_ids` list is how [CompanyOS](https://www.agno.com/blog/introducing-companyos) ties a Routine to its Product. It feeds the Routine count, the failed-Routine count in `/company/attention` and project auto-completion for `refresh` Routines.

In earlier releases a `metadata` edit replaced the whole dict and dropped the list. An agent with `SchedulerTools` or Studio's `update_schedule` could also delete a Routine and leave its id behind on the Product, re-enable one whose Product is archived or rewrite its message. We ran the same scenario on both releases against an AgentOS with `CompanyConfig` on SQLite.

![Real output from an AgentOS with CompanyConfig on SQLite, one Product with one intake Routine. Step 1, PATCH /company/products with metadata team b: before, routine_ids is empty; now, routine_ids still holds the Routine. Step 2, SchedulerTools.delete_schedule on the Routine: before, status deleted and the Product still lists the deleted id; now, error_type company_routine and the Routine stays linked.](https://www.agno.com/images/v3-1-7-company-routines-linked.png)

The refusal reads `Schedule <id> is a Company Routine. Change it through Company Routines.` Triggering a Routine from the tools still works, and plain schedules behave as before.

OS Manager now sends Company work to the right member. Its Company add-on delegates Products, Projects, Tasks, Sources and Routines, setup and status questions included, to Product Manager, so a request like "set up a daily routine for Docs" reaches the member that links the Routine to its Product.

Under `user_isolation=True`, the Company tools now follow the same ownership rules as the Company HTTP routes:

- Routines declared in code or YAML have no owner. Their Company tool calls used to fail with `Caller identity is required under user isolation`, and now run unscoped on their own Product.
- `edit_company_project` and `edit_company_task` let any writer edit, as the `PATCH` routes do.
- `refresh_company_product` archives only the caller's finished work.
- Any writer can add a Routine to a Product, and a new Routine from a `/company/setup` retry belongs to the caller.

See the [cookbook](https://github.com/agno-agi/agno/blob/main/cookbook/05_agent_os/30_company/08_custom_routines.py), and learn more about [Scheduler tools](https://docs.agno.com/tools/toolkits/agent-os/scheduler) in the documentation.
