Microsoft made a significant change to how Teams tabs work in the app manifest v1.16 that fundamentally altered not just the developer experience, but also the user experience.
The problem? They forgot to document it until I raised an issue about it. This undocumented change creates frustrating limitations for developers who want to build flexible Teams apps with multiple tab options.
In this article I’ll explain what changed, why it matters, and how you can work around these new limitations.
Understanding the original Teams tab model
When Microsoft first introduced Teams tabs, they gave developers two distinct options:
- Static tabs (personal apps): These tabs were always pinned to the left rail of the Teams app and available to users regardless of which team or channel they were in. Think of apps like Calendar, the Me app, or Copilot. They had no configuration options - once installed, they just worked as designed. The scope was limited to
personal
only. - Configurable tabs (channel tabs): These tabs required a configuration step during installation. When you added one to a channel, a dialog would appear asking for settings like which mapping service to use or what data to display. These tabs could only use
team
orgroupChat
scopes.
The key point here is that these scopes were mutually exclusive. A static tab could only be personal, and a configurable tab could only be added to teams or group chats.
What changed in Teams app manifest v1.16
Microsoft quietly removed these scope restrictions. Now static tabs can use personal
, team
, and groupChat
scopes in any combination. Sounds like more flexibility, right? Unfortunately, it created a major problem.
Here’s the issue: If your Teams app includes a static tab with scope: ["team"]
, the Teams client will always choose that static tab when adding tabs to channels, even if you also have configurable tabs defined in the same app.
This means that you’ve lost the ability to add configurable tabs to a channel if there is a single static tab if it’s scope
property contains team
.
This means you lose the ability to offer users multiple tab options with different configurations. The Teams client automatically selects the static tab and ignores your configurable alternatives entirely.
Worse yet, the project templates were updated in that they include a static tab that sets the scope
property to all options scope: ["personal", "team", "groupChat"]
by default!
This caught me by surprise so I raised an issue about it, which was ultimately confirmed by Microsoft. Not only did they acknowledge the change, but admitted they never updated the docs or announced the change. You can see the exchange for yourself in this issue:
MS: ... seems the description and some docs are not updated...
https://github.com/OfficeDev/teams-toolkit/issues/13755#issuecomment-2840615768

The real-world impact
Let’s say you’re building a project management app. You want to offer:
- A static tab that shows a dashboard (no configuration needed)
- Multiple configurable tabs for different project views (with user-selected settings)
Under the old way, you’d make the dashboard a personal-scoped static tab and the project views as team-scoped configurable tabs. Users could add whichever tab type they needed.
With the new way, if you give your static dashboard tab the team
scope, users can never access your configurable tabs through the normal tab installation process. The Teams client will always pick the static tab.
Working around the limitation
You have a few options to deal with this change:
Option 1: Separate apps
Create two separate Teams apps - one for static tabs with team scope and another for configurable tabs. This isn’t ideal because users have to install multiple apps from the same vendor to get full functionality.
Option 2: Programmatic installation
Use the Microsoft Graph API to programmatically add configurable tabs to channels. This requires building an administrative interface (typically within a personal tab) or a utility, (such as a CLI or script), where users can:
- Select which channel should receive the configurable tab
- Choose configuration settings
- Trigger the programmatic installation
const endpoint = `https://graph.microsoft.com/v1.0/teams/${context.team?.groupId}/channels/${context.channel?.id}/tabs`;
const requestObject = {
method: 'POST',
headers: {
authorization: `bearer ${msGraphOboToken}`,
'content-type': 'application/json'
},
body: JSON.stringify({
displayName: 'My Channel Tab',
'[email protected]' : `https://graph.microsoft.com/v1.0/appCatalogs/teamsApps/${teams-app-id}`,
configuration: {
entityId: 'f7d4e892-3b56-4c91-a8f2-9e6c5d4b7a03',
contentUrl: 'https://my-teams-app.com/tab',
removeUrl: 'https://my-teams-app.com/remove,
websiteUrl: 'https://my-teams-app.com/app'
}
})
};
await fetch(endpoint, requestObject);
Option 3: Stick with the old model
Keep static tabs as personal-only ("scope":["personal"]
) and configurable tabs as "scope":["team","groupChat"]
only. This maintains the traditional behavior, but limits your options with your non-configurable tab in that it can only be used in personal apps.
My take on this change
I think this change is a step backward. Microsoft forced developers to write additional code just to achieve functionality that previously worked out of the box. It’s not intuitive, and they didn’t bother documenting it until the community raised issues.
The change feels like a regression that prioritizes some internal Microsoft logic over the developer, ISV, or user experience. I don’t understand how this is seen as an improvement when you have to tell developers they need to build administrative interfaces and write Graph API code just to install configurable tabs. Or, you just create two Teams apps.
Learn Microsoft Teams development the right way
Tired of discovering these undocumented changes the hard way?
Join my upcoming Introduction to Microsoft Teams Application Development FREE webinar on September 15 where I cover the real-world patterns Microsoft doesn’t tell you about:
Join Andrew in this webinar for SPFx, Power Apps, and Microsoft 365 developers to learn Microsoft Teams customizations, bots, message extensions, and more!
https://www.voitanos.io/webinars/microsoft-teams-app-dev-overview-20250915/

Or if you’re ready to become a Teams development expert, check out the next cohort of my Microsoft Teams AppDev Accelerator program… some early-bird seats are still available!
Learn Microsoft Teams app development faster to be the irreplaceable expert delivering more to your customers!
https://www.voitanos.io/course-msteams-appdev-accelerator/

Moving forward
If you’re building new Teams apps or updating existing ones, you need to carefully consider your tab strategy. Think about whether you really need static tabs with team scope, or if you can design around the limitations.
For apps that genuinely need both static team-scoped tabs and configurable tabs, plan for the additional development work required to build programmatic installation features.
What’s next
This change highlights the importance of staying on top of Microsoft’s platform updates, even when they’re not properly documented. The Teams development landscape continues to evolve rapidly, and sometimes these changes create unexpected challenges.
Share this with your team if they’re building Teams apps - it’ll save them hours of debugging!
Have you run into this issue with your Teams apps? What do you think about this “improvement” to Teams tab development?

Microsoft MVP, Full-Stack Developer & Chief Course Artisan - Voitanos LLC.
Andrew Connell is a full stack developer who focuses on Microsoft Azure & Microsoft 365. He’s a 21-year recipient of Microsoft’s MVP award and has helped thousands of developers through the various courses he’s authored & taught. Whether it’s an introduction to the entire ecosystem, or a deep dive into a specific software, his resources, tools, and support help web developers become experts in the Microsoft 365 ecosystem, so they can become irreplaceable in their organization.