OfficeDev / OfficeDev/Office-Addin-Scripts
validateManifest: false-positive "must NOT have additional properties" (builtInGroupId, overriddenByRibbonApi) for ribbon groups on a built-in tab (builtInTabId)
@millerds is already working on this.
Since Jun 15, 2026.
- Dominant language
- TypeScript
- Stars
- 194
- Forks
- 117
- Avg merge
- 1d 32m
- Merged PRs (30d)
- 2
Description
Expected behavior
validateManifest (and office-addin-manifest validate) should report a unified (JSON) manifest as valid when a ribbon button is added to a built-in tab using ribbons[].tabs[].builtInTabId (e.g. "TabHome") together with a custom group that declares id, label, and controls.
This is the documented structure for adding a custom button to a built-in tab, the TeamsManifestV1D25 typings allow builtInTabId on the tab, and Office renders the button correctly from this manifest.
Current behavior
validateManifest returns isValid: false with two errors, even though the group declares neither of the named properties:
/extensions/0/ribbons/0/tabs/0/groups/0 must NOT have additional properties. Details: {"additionalProperty":"builtInGroupId"}
/extensions/0/ribbons/0/tabs/0/groups/0 must NOT have additional properties. Details: {"additionalProperty":"overriddenByRibbonApi"}
The group in the input manifest only contains controls, icons, id, and label. builtInGroupId and overriddenByRibbonApi are never declared — they appear to be injected during conversion and then rejected by the schema applied to groups under a builtInTabId tab.
Observations:
- Reproduces for every group shape under
builtInTabId— with or without groupicons, and even a minimal{ id, label, controls }group. - Removing
builtInTabId(e.g. switching to a custom tab withid+label+position) makes validation pass — but then the button cannot be anchored to a built-in tab such as Home, so this isn't a viable workaround for the documented scenario. - Net effect: there is no way to validate a manifest that puts a custom ribbon button on a built-in tab, despite that being the documented and runtime-correct structure.
The relevant tab/group (the only part that matters for the repro):
{
"builtInTabId": "TabHome",
"groups": [
{
"id": "ContosoCommandsGroup",
"label": "Contoso",
"icons": [
{ "size": 16, "url": "https://contoso.com/assets/icon-16.png" },
{ "size": 32, "url": "https://contoso.com/assets/icon-32.png" },
{ "size": 80, "url": "https://contoso.com/assets/icon-80.png" }
],
"controls": [
{
"id": "ContosoTaskpaneButton",
"type": "button",
"label": "Open Contoso",
"actionId": "OpenTaskPane",
"enabled": true,
"icons": [
{ "size": 16, "url": "https://contoso.com/assets/icon-16.png" },
{ "size": 32, "url": "https://contoso.com/assets/icon-32.png" },
{ "size": 80, "url": "https://contoso.com/assets/icon-80.png" }
],
"supertip": { "title": "Open Contoso", "description": "Open the Contoso task pane" }
}
]
}
]
}
Steps to Reproduce
- Save the full manifest below as
manifest.json(a minimal Excel task pane unified manifest whose single ribbon tab targets the built-in Home tab viabuiltInTabId: "TabHome"). - Validate it:
(or callnpx office-addin-manifest validate manifest.jsonvalidateManifest("manifest.json")fromoffice-addin-manifest.) - Validation fails with
isValid: falseand the twomust NOT have additional propertieserrors shown above, even though neitherbuiltInGroupIdnoroverriddenByRibbonApiis present in the manifest.
Full minimal manifest.json
{
"$schema": "https://developer.microsoft.com/json-schemas/teams/v1.25/MicrosoftTeams.schema.json",
"manifestVersion": "1.25",
"id": "00000000-0000-0000-0000-000000000000",
"version": "1.0.0",
"name": { "short": "Contoso Excel", "full": "Contoso Excel Add-in" },
"description": {
"short": "A minimal Contoso task pane add-in.",
"full": "A minimal Contoso task pane add-in that anchors a ribbon button to the Home tab."
},
"developer": {
"name": "Contoso",
"websiteUrl": "https://contoso.com",
"privacyUrl": "https://contoso.com",
"termsOfUseUrl": "https://contoso.com"
},
"icons": { "color": "assets/color.png", "outline": "assets/outline.png" },
"accentColor": "#338080",
"validDomains": ["contoso.com"],
"showLoadingIndicator": false,
"isFullScreen": false,
"defaultBlockUntilAdminAction": false,
"localizationInfo": { "defaultLanguageTag": "en-us", "additionalLanguages": [] },
"authorization": {
"permissions": {
"resourceSpecific": [{ "name": "Document.ReadWrite.User", "type": "Delegated" }]
}
},
"extensions": [
{
"requirements": { "scopes": ["workbook"] },
"getStartedMessages": [
{
"title": "Contoso Excel add-in loaded",
"description": "Go to the Home tab and open the Contoso task pane.",
"learnMoreUrl": "https://contoso.com",
"requirements": { "formFactors": ["desktop"], "scopes": ["workbook"] }
}
],
"alternates": [
{
"alternateIcons": {
"icon": { "size": 32, "url": "https://contoso.com/assets/icon-32.png" },
"highResolutionIcon": { "size": 64, "url": "https://contoso.com/assets/icon-64.png" }
}
}
],
"ribbons": [
{
"contexts": ["default"],
"requirements": {
"capabilities": [{ "name": "AddinCommands", "minVersion": "1.1" }],
"formFactors": ["desktop"],
"scopes": ["workbook"]
},
"tabs": [
{
"builtInTabId": "TabHome",
"groups": [
{
"id": "ContosoCommandsGroup",
"label": "Contoso",
"icons": [
{ "size": 16, "url": "https://contoso.com/assets/icon-16.png" },
{ "size": 32, "url": "https://contoso.com/assets/icon-32.png" },
{ "size": 80, "url": "https://contoso.com/assets/icon-80.png" }
],
"controls": [
{
"id": "ContosoTaskpaneButton",
"type": "button",
"label": "Open Contoso",
"actionId": "OpenTaskPane",
"enabled": true,
"icons": [
{ "size": 16, "url": "https://contoso.com/assets/icon-16.png" },
{ "size": 32, "url": "https://contoso.com/assets/icon-32.png" },
{ "size": 80, "url": "https://contoso.com/assets/icon-80.png" }
],
"supertip": { "title": "Open Contoso", "description": "Open the Contoso task pane" }
}
]
}
]
}
],
"runtimes": [
{
"id": "TaskPaneRuntime",
"type": "general",
"lifetime": "short",
"code": { "page": "https://contoso.com/taskpane" },
"actions": [{ "id": "OpenTaskPane", "type": "openPage" }],
"requirements": {
"capabilities": [{ "name": "AddinCommands", "minVersion": "1.1" }],
"formFactors": ["desktop"]
}
}
]
}
]
}
]
}
Context
- Operating System: reproduces regardless of OS (validation is static); observed on macOS.
- Node version: v24.15.0
- Office version: N/A — the manifest is validated statically, not against an installed Office build.
- Tool version:
office-addin-manifest2.1.5 (latest at time of filing)
Failure Logs
$ npx office-addin-manifest validate manifest.json
/extensions/0/ribbons/0/tabs/0/groups/0 must NOT have additional properties. Details: {"additionalProperty":"builtInGroupId"}
/extensions/0/ribbons/0/tabs/0/groups/0 must NOT have additional properties. Details: {"additionalProperty":"overriddenByRibbonApi"}
The manifest only declares controls, icons, id, and label on the group; builtInGroupId / overriddenByRibbonApi are reported as disallowed additional properties despite never being present in the input, which points to them being injected during the JSON-manifest conversion and then failing the group schema selected for a builtInTabId tab.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.