End-to-end process of building, validating, and distributing custom apps and add-ins across Microsoft 365 platforms
The error occurs because the Microsoft 365 app shell expects a static tab experience for a Teams app opened from the Microsoft 365 app launcher, but the app either has no valid staticTabs entry or the static tab configuration is invalid for the host.
Key points from the behavior described:
- The app works in Teams (desktop/web) as a chat/agent and can be opened as a Copilot chat.
- From the Microsoft 365 app page, it fails with:
Unable to load requested application. No static tabs are configured. - When
staticTabswere added withcontentUrl/websiteUrl, the app stopped working even in Teams, which indicates the tab configuration did not meet manifest or runtime requirements.
To open the app from the Microsoft 365 app page without this error, the manifest must:
- Use a manifest schema version that supports Microsoft 365 hosts
- Ensure the manifest uses schema
1.13or later and a correspondingmanifestVersion, for example:{ "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.20/MicrosoftTeams.schema.json", "manifestVersion": "1.20" } - This is required for a Teams personal tab (or agent with a tab) to run in Outlook and the Microsoft 365 app.
- Ensure the manifest uses schema
- Define at least one valid static tab in personal scope
- The Microsoft 365 app shell needs a static tab to render when the app is launched from the app launcher. Configure
staticTabssimilar to:"staticTabs": [ { "entityId": "index", "name": "Personal Tab", "contentUrl": "${{TAB_ENDPOINT}}/index.html#/tab", "websiteUrl": "${{TAB_ENDPOINT}}/index.html#/tab", "scopes": [ "personal" ] } ], - Ensure:
-
entityIdis present (required). -
contentUrlandwebsiteUrlare valid HTTPS URLs. - The domain of
contentUrl/websiteUrlis either the same as the settings page domain or listed invalidDomains.
-
- The Microsoft 365 app shell needs a static tab to render when the app is launched from the app launcher. Configure
- Configure
validDomainsto match the tab URLs- Add the tab’s domain to
validDomains, for example:"validDomains": [ "${{TAB_DOMAIN}}" ], - If using Agents Toolkit variables (
${{TAB_ENDPOINT}},${{TAB_DOMAIN}}), ensure they resolve correctly in the environment where the app is running.
- Add the tab’s domain to
- Keep the chat/agent capability and static tab aligned via runtime requirements (optional but recommended)
- If using
elementRelationshipSetand runtime requirement sets, ensure they do not exclude the static tab from Microsoft 365 hosts. The Microsoft 365 host must see at least one static tab capability that is allowed to run there.
- If using
- Validate and troubleshoot the manifest and package
- Use Agents Toolkit to validate the manifest and identify schema or configuration errors.
- If the app fails to open in Teams after adding
staticTabs, re-check:- JSON validity.
- That
staticTabsis an array of unique items and within the allowed limit. - That all URLs are HTTPS and domains are in
validDomains.
- If manifest updates are not reflected, sign out and sign in again to clear cache.
- Understand host support and adjust behavior at runtime
- Only a subset of Teams capabilities is supported in Outlook and Microsoft 365. Use the Teams JS SDK
isSupported()checks for capabilities and provide fallback UI if a capability is not supported in the Microsoft 365 host.
- Only a subset of Teams capabilities is supported in Outlook and Microsoft 365. Use the Teams JS SDK
In practice, the correct solution is:
- Upgrade the manifest to a supported schema/manifest version for Microsoft 365.
- Add a valid personal-scope static tab with working
contentUrl/websiteUrland matchingvalidDomains. - Ensure no runtime requirement or relationship configuration hides that static tab from the Microsoft 365 host.
Once a valid personal static tab is present and the manifest is on a supported schema, the app should open from the Microsoft 365 app page instead of showing the “No static tabs are configured” error, while still functioning as a Copilot chat.
References: