-
Notifications
You must be signed in to change notification settings - Fork 35
Description
Describe the bug
When running backstage-cli config:check --strict in an application that uses the Jira Dashboard plugin, the configuration validation fails with contradictory errors at the top-level jiraDashboard key:
- First scenario: Properties like
token,baseUrl,useApiV3, etc. are flagged as "additional properties" that are not allowed at/jiraDashboard - Second scenario: After removing
token, the validator reports that/jiraDashboardmust have the required propertytoken(or alternativelyinstances) while simultaneously flagging other fields as "additional properties"
Expected behavior:
Using the “single instance” form of the backend config (i.e., jiraDashboard.token, jiraDashboard.baseUrl, etc) should validate successfully alongside the frontend config that only exposes annotationPrefix.
Actual behavior:
Strict config validation fails with mutually exclusive errors, suggesting that incompatible schemas are being applied to the same config path.
To reproduce
Steps to reproduce the behavior:
- Add the following to
app-config.yaml:
jiraDashboard:
token: ${token}
userEmailSuffix: "@domain.com"
baseUrl: "https://domain.atlassian.net/rest/api/3/"
useApiV3: true
defaultFilters:
- name: "statusCategoryFilter"
shortName: "statusCategoryFilter"
query: "statusCategory != Done ORDER BY created DESC"- Execute the configuration check:
yarn backstage-cli config:check --strict --lax \
--config app-config.yaml- Observe the errors. Example stderr:
Error: Configuration does not match schema
Config must NOT have additional properties { additionalProperty=token } at /jiraDashboard
Config must NOT have additional properties { additionalProperty=userEmailSuffix } at /jiraDashboard
Config must NOT have additional properties { additionalProperty=baseUrl } at /jiraDashboard
Config must NOT have additional properties { additionalProperty=useApiV3 } at /jiraDashboard
Config must NOT have additional properties { additionalProperty=defaultFilters } at /jiraDashboard
- Now remove token to test again:
jiraDashboard:
userEmailSuffix: "@domain.com"
baseUrl: "https://domain.atlassian.net/rest/api/3/"
useApiV3: true
defaultFilters:
- name: "statusCategoryFilter"
shortName: "statusCategoryFilter"
query: "statusCategory != Done ORDER BY created DESC"- Run the same strict check again. Example stderr:
Error: Configuration does not match schema
Config must have required property 'token' { missingProperty=token } at /jiraDashboard
Config must have required property 'instances' { missingProperty=instances } at /jiraDashboard
Config must NOT have additional properties { additionalProperty=userEmailSuffix } at /jiraDashboard
Config must NOT have additional properties { additionalProperty=baseUrl } at /jiraDashboard
Config must NOT have additional properties { additionalProperty=useApiV3 } at /jiraDashboard
Config must NOT have additional properties { additionalProperty=defaultFilters } at /jiraDashboard
Config must match a schema in anyOf { } at /jiraDashboard
Screenshots
N/A
Environment
- OS and version: macOS (Apple Silicon), Node 20.x
- Package manager: Yarn
- Backstage CLI: backstage-cli config:check --strict --lax
- Version: latest plugin versions as of Oct 2025 (can provide exact versions if needed)
- Stack trace or logs: see stderr in “To reproduce”.
Additional context
From the published TypeScript config types:
Backend config
Frontend config
Two likely root causes
1. Schema Name Collision
Both the frontend and backend packages declare schemas at the same path (/jiraDashboard):
- Frontend schema: Only allows
annotationPrefix - Backend schema: Allows either single-instance fields (
token,baseUrl, etc.) or aninstances[]array
In Backstage's strict validation mode, schemas from multiple packages are combined. The effective constraint on /jiraDashboard appears to become an intersection that disallows the backend's fields (reported as "additional properties") while also sometimes requiring token/instances, resulting in contradictory errors depending on which validation path executes first.
2. Union Type Conflict
The backend's jiraDashboard uses a oneOf constraint (single-instance OR multi-instance), while the frontend's jiraDashboard is a narrow object containing only annotationPrefix. When merged during strict checking, the validation logic attempts to satisfy both the frontend's narrow object schema AND one of the backend's union branches simultaneously.
This creates an impossible validation scenario whenever backend-only fields like token or baseUrl are included, producing alternating "additional property" versus "missing required property" errors.RetryClaude does not have the ability to run the code it generates yet.