What is your developer-dependent CMS actually costing you? Calculate your costs and get a full report
What is your developer-dependent CMS actually costing you? Calculate your costs and get a full report
Vibe Coding
The silent failures that cost the most time when building Agility sites with AI tools and the MCP server: pull dates, saves that don't publish, page publishing, wiped fields, reordering, reference names, string values and preview domains.
Most of the time lost in our proof-of-concept builds (see Vibe Coding with Agility) wasn't spent writing code. It went on behavior that fails silently: a call reports success, and the site doesn't show what you expect. These are the gotchas that cost the most time, with the symptom, the reason and what to do.
Copy the ones that apply into the "MCP gotchas" list in your AGENTS.md (see Writing an AGENTS.md for Agility Projects), so your AI coding tool reads them before it starts.
Where this article says we have seen, the behavior comes from our builds and isn't described in the product documentation. Treat it as something to check for, not as documented behavior.
| Gotcha | Rule for AGENTS.md |
|---|---|
| A past pull date hides an item | Save with null release and pull dates unless you mean to schedule. |
| Saving never publishes | Nothing is live until it's published. Check against the published key. |
| Publishing a page doesn't publish its components | Publish the component content too, then check the live page. |
| Updates replace the whole item | Fetch, merge, then save, with every field. |
| Component reordering doesn't take effect | Set the order with two page saves, then read the page back. |
| Reference names are normalized | Read the name back from the save result and use that. |
| Numbers can arrive as strings | Convert field values explicitly in the data layer. |
| One preview domain per instance | Plan multi-site preview routing up front. |
Symptom. An item saves without error and shows in the Agility app, but never appears in the published API or on the site.
Why. A pull date takes an item down from the site once it passes, and a release date keeps an item off the site until it passes (see Schedule Content Changes). An item saved with a pull date that's already in the past is taken down as soon as it would go live. This happens easily when an AI tool fills in date properties itself, or copies them from an older item. The MCP server's save_content_items also interprets release and pull dates in Eastern time, so a date that looks a few hours in the future can already be past.
What to do. Tell the AI tool to send null for release and pull dates on every save unless you're deliberately scheduling content. When an item is missing from the live site, check its release and pull dates before anything else.
Symptom. The AI tool reports that content was created, and you can see it in preview and in development, but it's missing on the deployed site.
Why. save_content_items always saves to the instance's default workflow state, usually Staging. Any state you pass on save is ignored. Saving a change to a published item creates a new Staging version and leaves the live version as it was. In development, the Agility Next.js Starter always fetches with the preview API key, so staged content renders locally and hides the problem.
What to do. Publish deliberately, with publish_content and publish_page, at the publishing level your team has chosen (see Governing AI Access to Agility CMS). Before a demo or a launch, check the site against the published fetch key in a fresh incognito window, not just in development.
Symptom. You publish a page and it appears on the site, but some of its components are missing, empty or out of date.
Why. A page and the content items its components use are separate things to publish. Publishing a page and the content it depends on in one step is a distinct "cascade" operation (the .NET Management SDK exposes it as PublishPageCascadeAsync), not what a plain page publish does.
What to do. After publishing a page, publish the content items its components use. Then load the live page and confirm each component shows the latest content. The publish tools accept up to 50 IDs per call; we have seen large publish batches time out, and batches of 16 or fewer were reliable.
Symptom. You ask the AI tool to change one field, and other fields on the item come back empty.
Why. An update through save_content_items replaces the item. Any field you leave out is wiped. Models behave the same way: when you save a content or component model, undefined field properties are treated as empty, and saving a page model with a zone left out removes that zone (and the components placed in it).
What to do. Always fetch, merge, then save: get_content_item for the current fields and versionID, change only what you mean to change, and send every field back. Do the same for models with get_content_model_details or get_component_model_details. Read the item back after saving to confirm nothing was lost.
Symptom. reorder_page_modules returns success and the page's version number goes up, but the components are still in the old order.
Why. reorder_page_modules currently reports success without changing the order. save_page doesn't reorder either: it ignores the order of the zone array for components already on the page. Existing components keep their old order, and new ones are appended after them.
What to do. Set the order with two saves. First save the page with only the components you want at the top, then save it again with the rest appended in the order you want. Components re-added this way are cloned to new content IDs, in array order, so record the new IDs in your instance ledger. The original component items become unused once the new page version is published. Read the page back with get_page after each save to confirm the order and the content IDs.
Symptom. Code that fetches a list by the reference name you asked for returns nothing, or a linked-content dropdown renders blank in the editor.
Why. Reference names aren't always stored exactly as you typed them. The read API returns container reference names lowercased, and the MCP server normalizes linked-content reference names to the container's canonical case when you save. We have also seen container reference names shortened on creation, and in our builds a reference name couldn't be changed once the container existed.
What to do. After creating a container or model, take the reference name from the save result or from get_containers, record it in your instance ledger, and use that value in code. When writing a User Selectable linked-content field, use the exact case get_containers returns.
Symptom. A comparison or sort on a numeric field gives odd results, or a true/false toggle is always treated as true.
Why. We have seen number and boolean field values come back from the Fetch API as strings, such as "12" and "false". The string "false" is truthy in JavaScript.
What to do. Convert field values explicitly in your data layer (Number(...), value === "true"), and type the converted shape, not the raw response. Dates deserve the same care: we have seen date fields shift by the instance's time zone, so test a date field with a value near midnight.
Symptom. In a multi-site build, clicking Preview for one site opens another site's domain.
Why. We have seen an instance support only one preview domain, which doesn't fit a build where several sites share one instance. The preview setup itself is described in Setting Up Preview.
What to do. Plan multi-site preview routing up front. One approach that worked: pass a site or channel identifier on the preview URL, and have the preview route redirect to the right site's hostname before it turns on draft mode.