Appearance
Common Issues
This guide covers common issues you may encounter with custom widgets — including build failures, content safety rejections, Content Security Policy errors, content propagation delays, and installation suspension — and how to resolve them.
Prerequisites
- Familiarity with Connect Your GitHub Account
- Understanding of Repository & Branch Settings
Session and Rate Limiting Issues
Connection keeps failing after multiple attempts
Root cause: Repeated connection attempts in quick succession can trigger rate limiting.
Solution:
- Stop trying to connect
- Wait at least one hour
- Clear your browser cache and cookies
- Try again with a fresh browser session
OAuth flow suddenly stopped working
Root cause: Your connection session expired. Sessions are valid for approximately 30 minutes.
Solution:
- Return to Sources settings
- Click Manage Accounts to start fresh
- Complete the entire flow in one session
Tip: Keep the connection flow tab active and don't navigate away during the process.
Connection Issues
My organization doesn't appear in the picker
Possible causes:
- You're not a member of that organization on GitHub
- The GitHub App isn't installed on that organization
- Your organization requires admin approval
Solutions:
- Verify membership: Go to GitHub and confirm you're a member of the organization
- Install the app: Click "Install on New Account" to add the app to your organization
- Request approval: If you see "Request" instead of "Install", your org requires admin approval — see Admin Approval
OAuth error page displayed
Possible causes:
- Session expired during authorization
- Browser cookies blocked
- Conflicting GitHub sessions
- GitHub API rate limiting (too many requests)
Solutions:
- Clear session: Sign out of GitHub completely, then sign back in
- Clear cookies: Clear browser cookies for both GitHub and this platform
- Try incognito: Use an incognito/private browser window
- Check extensions: Disable browser extensions that might interfere with OAuth
- Wait and retry: If rate limited, wait a few minutes before trying again
Connection times out
Possible causes:
- Network issues
- GitHub API unavailable
- Server-side processing delay
Solutions:
- Check internet: Verify your internet connection is working
- Check GitHub status: Visit githubstatus.com for outages
- Retry: Wait a few minutes and try again
- Talk to your Gainsight team: If timeouts persist, talk to your Gainsight team
How do I remove a GitHub account from my community
Use Disconnect on the Manage GitHub accounts page. Open this page via Manage Accounts from Sources. That only removes the link for your community; it does not uninstall the app from GitHub. The account will appear under "Available to connect" if you want to reconnect later. To remove the app from the organization entirely (affects all communities), see Multiple Organizations — Option B.
I disconnected by mistake
Click Manage Accounts again. The account appears under Available to connect. Select it and click Connect Selected to reconnect.
Repository Issues
Repository not showing after connection
Possible causes:
- App doesn't have access to that repository
- Repository was added after app installation
- Cache not refreshed
Solutions:
- Check app permissions: Go to GitHub → Organization Settings → Installed Apps → Configure and verify repository access
- Grant access: Add the missing repository to the app's access list
- Refresh: Click the refresh button or reload the page
- Reconnect: Click Manage Accounts again to refresh your connection
Repository was working but suddenly stopped updating
Possible causes:
- The watched branch was deleted on GitHub
- The GitHub App was removed from the repository's access list
- The installation was suspended
Solutions:
- Check the branch exists: Go to GitHub and verify the watched branch still exists in the repository
- Check app access: Go to GitHub → Organization Settings → Installed Apps → Configure, and verify the repository is in the access list
- Check installation status: If you see any suspension notices, contact your GitHub organization admin
Build status stuck on Failed
Possible causes:
- Invalid widget configuration
- Missing required files
- Syntax errors in configuration
- Referenced assets not found
Solutions:
- Check error details: In Integrations → Developer Studio → Sources, find the repository, and click the build status indicator to see the error details
- Validate configuration: Check your
extensions_registry.jsonagainst Registry Reference and the per-type references (Widget Definition Reference, Script Definition Reference, Stylesheet Definition Reference) to ensure all required fields are present and values are correct - Check file paths: Verify all referenced files exist in the repository
- Push a fix: Correct the issue and push a new commit to retry
Common configuration errors:
| Error | Cause | Fix |
|---|---|---|
| "Invalid JSON" | Syntax error in config | Run config through a JSON validator |
| "Missing required field" | Config incomplete | Add the missing field |
| "File not found" | Asset doesn't exist | Check file path or add the file |
Some widgets publish but others fail
Root cause: Individual widget content files may be missing or inaccessible.
Solution:
- Check the build status details to see which specific widgets failed
- Verify each widget's
source.pathandsource.entrypoint to an existing directory and file - Ensure all files are committed to the watched branch
- Push a fix and the system will retry automatically
Static Widget (Source Block) Issues
Path traversal detected
Error code: PATH_TRAVERSAL_DETECTED
The source.path or source.entry contains ../. See Error Codes for the cause and fix.
Entry file not found
Error code: ENTRY_FILE_NOT_FOUND
The HTML file named in source.entry doesn't exist in source.path. See Error Codes for the cause and fix.
Directory exceeds limits
Error codes: MAX_FILES_EXCEEDED, MAX_SIZE_EXCEEDED
The widget directory has more than 100 files or exceeds 10 MB. See Error Codes for the cause and fix.
Invalid widget structure
Error code: INVALID_WIDGET_STRUCTURE
A widget has both source and content blocks, or neither — it must have exactly one. See Error Codes for the cause and fix.
Assets not loading in my widget
Root cause: JavaScript files dynamically loading assets use relative paths that aren't transformed.
Solution: Asset transformations only apply to HTML. For JS dynamic loading:
- Use a base URL variable passed from HTML
- Inline small assets as data URLs
- Preload assets in HTML where paths get transformed
See Hosting Widgets for related configuration details.
For a complete list of error codes and resolution guidance, see Error Codes.
Build fails with no visible error
Root cause: The extensions_registry.json file has a structural problem.
Common issues:
- Invalid JSON syntax (missing commas, unclosed braces)
- Missing
widgetsarray at the root level widgetsis not an array (e.g., it's an object or string)
Solution:
- Validate your JSON using an online validator or IDE
- Ensure the file structure is:
{"widgets": [...]} - Check for trailing commas (not allowed in JSON)
Scripts & Stylesheets Issues
These issues affect global scripts and stylesheets declared in the scripts and stylesheets arrays of extensions_registry.json, not widgets.
Script or stylesheet doesn't load on the expected pages
Root cause: The entry's rules don't match the page you're viewing.
Solutions:
- All rules must match — multiple rules use AND logic, so one rule that never matches keeps the asset off the page.
- Check the field is present on that page —
pageis only set on customizable and overview pages,pageTypeonly on category and custom pages, andslugonly on custom pages. A rule against a field that's absent on the current page never matches. - Match all categories with
pageType— for category and custom pages thepagevalue always includes the ID suffix (e.g.category/123), sopageequal tocategorynever matches. UsepageType(categoryorcustomPage) instead. - Use string values for
authenticated— match against"true"or"false", not a boolean. - Match the value shape to the operator — use a string with
eq/neqand an array within/not_in.
See Page Targeting for the full rule language and context fields.
An HTML attribute has no effect
Root cause: The attributes object maps each attribute name to a string value, and boolean attributes use an empty string rather than true.
Solution: Write boolean attributes like defer and async with an empty-string value:
json
"attributes": { "defer": "" }1
This renders as <script src="..." defer></script>. See Script Definition Reference and Stylesheet Definition Reference for the supported attributes.
An external script or stylesheet URL doesn't load
Root cause: When path is an external URL, the platform injects a tag pointing straight at that URL — it does not fetch, publish, or proxy the file. Whether it loads depends entirely on the external host.
Solutions:
- Confirm the URL is reachable — open it directly in a browser and verify it serves the file.
- Keep the required extension —
pathmust end in.jsfor scripts and.cssfor stylesheets even for external URLs, or the entry fails validation. - Handle CORS if needed — if the external host requires it, set the
crossoriginattribute ("anonymous"or"use-credentials").
Widget Runtime Issues
These issues occur after a widget is published and running in the browser, not during the build phase.
Widget shows 'Loading...' but connector executes successfully
Root cause: document.querySelector() cannot reach elements inside Shadow DOM. The connector response arrives, but your code fails to find the DOM element to update.
Solution: Query elements through the widget's shadow root, not document:
js
var hosts = document.querySelectorAll(
'gs-cc-registry-widget[data-widget-type*="your_widget_type"]'
);
hosts.forEach(function(host) {
var root = host.shadowRoot;
if (root) {
var el = root.querySelector('.status');
// update el here
}
});1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
See Rendering & DOM for the full pattern.
Only one widget instance updates, others stay on 'Loading...'
Root cause: Using querySelector (returns the first match only) instead of querySelectorAll.
Solution: Use querySelectorAll and iterate over all host elements:
js
// Wrong: querySelector returns only the first match
var host = document.querySelector('gs-cc-registry-widget[data-widget-type*="weather"]');
// Correct: querySelectorAll iterates all instances
var hosts = document.querySelectorAll('gs-cc-registry-widget[data-widget-type*="weather"]');
hosts.forEach(function(host) { /* update each instance */ });1
2
3
4
5
6
2
3
4
5
6
See Rendering & DOM.
Content Security Issues
Widget rejected due to a policy violation
Error code: CONTENT_SCAN_REJECTED
Cause: Your widget code contains patterns that match a content safety rule. The error message includes the specific categories.
Resolution by category:
| Category | What to change |
|---|---|
crypto_mining | Remove cryptocurrency mining scripts entirely |
data_exfiltration | Remove code that sends user data to external servers. If you need to send data, use a Connector instead |
phishing_redirect | Remove fake login forms or deceptive redirects. Use your platform's built-in authentication |
obfuscation | Replace obfuscated code with readable source. If you use a bundler, check that its output is not overly minified |
external_script_loading | Load scripts from trusted sources only, or bundle dependencies into your widget directory |
credential_exposure | Remove hardcoded secrets from your code. Use environment variables, a secrets manager, or Connectors to handle credentials securely |
See Content Security for full details.
My widget breaks after security headers were added
Cause: The Content Security Policy restricts certain code patterns for security.
| Symptom | Cause | Fix |
|---|---|---|
eval() throws an error | CSP blocks eval() and new Function() | Rewrite code to avoid runtime evaluation |
| External script fails to load | CSP restricts script sources to 'self', inline, and trusted CDNs (see Content Security) | Load scripts from trusted CDNs or bundle them into your widget directory |
| Styles not applying | Unlikely — inline styles are allowed | Check for @import from external domains |
| Widget not rendering in an iframe | X-Frame-Options limits embedding | Widgets render within the platform's frame — this is expected behavior |
Publishing Issues
Widgets not updating after push
Checklist:
Correct branch? — Push must be to the watched branch
- Check which branch is configured in repository settings
- Pushes to other branches don't trigger updates
Repository enabled? — Disabled repos don't sync
- Verify the repository is enabled in settings
Build successful? — Failed builds don't publish
- Check build status for errors
Content propagation — Updates may take a few minutes
- Wait 2-3 minutes for content to propagate
Browser cache — Old content may be cached locally
- Hard refresh: Ctrl+Shift+R (Windows) or Cmd+Shift+R (Mac)
- Or try incognito mode
Wrong content being served
Possible causes:
- Watching the wrong branch
- Cache serving old content
- Build failed silently
Solutions:
- Verify branch: Check that you're watching the intended branch
- Clear cache: Hard refresh or clear browser cache
- Check build: Verify the latest build completed successfully
- Wait for propagation: Updates can take a few minutes to propagate
Content appears corrupted or incomplete
Solutions:
- Check source files: Verify files in repository are correct
- Re-trigger build: Push an empty commit to force a new buildbash
git commit --allow-empty -m "Trigger rebuild" git push1
2 - Check encoding: Ensure files use UTF-8 encoding
Fewer extensions published than expected
Root cause: A successful build skips extensions that don't need republishing, so the published count can be lower than the number you declared.
An extension is skipped when:
- Its content hasn't changed since the last publish
- It uses an external URL endpoint, which the platform doesn't host
Skipped extensions are not an error — they didn't need updating. Check the build status details to see which were skipped.
Installation Issues
If your installation appears suspended, see Suspension Issues for diagnosis and reactivation steps.
All my organizations disappeared
Root cause: Your GitHub authentication may have expired or been revoked.
Solution:
- Click Manage Accounts again to refresh your authentication
- Re-authorize the application if prompted
- Your organizations should reappear in the picker
Suspension Issues
Installation suspended by GitHub
GitHub may suspend app installations for various reasons:
Common causes:
- Organization billing issues
- Policy violations
- Admin action
Solutions depend on who suspended the installation:
- If suspended by GitHub: Check GitHub notifications for the reason, then resolve any billing or policy issues with GitHub support. After resolution, you may need to reinstall the app.
- If suspended by your organization admin: Ask the admin for details. They can see the suspension reason in GitHub's organization settings and reactivate in Settings → Integrations → Applications.
If you are unsure which applies, contact your GitHub organization admin first — they can see the suspension reason and act directly.
How to reactivate a suspended installation
- Resolve the underlying issue with GitHub (billing, policy, or admin action)
- Go to GitHub Organization Settings → Installed Apps
- Find the app and reactivate or reinstall
- Return to your Sources and reconnect if needed
Authentication Issues
Suddenly lost access to connected organizations
Possible causes:
- GitHub token expired
- Removed from organization on GitHub
- App permissions changed
Solutions:
- Reconnect: Try connecting to GitHub again to refresh tokens
- Check membership: Verify your GitHub organization memberships
- Review permissions: Check app permissions in GitHub settings
Getting 'Forbidden' errors
Solutions:
- Refresh connection: Click Manage Accounts again to refresh your connection
- Check permissions: Verify the app has required permissions in GitHub
- Clear session: Sign out and back in
Performance Issues
Builds taking too long
Normal build times:
- Small repos: A few seconds
- Medium repos: Under a minute
- Large repos: A few minutes
If builds are unusually slow:
- Check repo size: Very large repos take longer
- Check GitHub status: GitHub API slowdowns affect build times
- Stuck In Progress: If a build stays In Progress for more than 10 minutes, talk to your Gainsight team
- Talk to your Gainsight team: Persistent slowness may indicate an issue
Frequent build failures
Solutions:
- Review patterns: Look for common causes in your build history in Integrations → Developer Studio → Sources
- Validate locally: Run your
extensions_registry.jsonthrough a JSON validator and review Registry Reference - Check dependencies: Ensure all files referenced in
source.pathandsource.entryexist in the repository
Widget Development Issues
Widget renders nothing
- Verify the
<div id="root"></div>(or your chosen mount point) exists in your widget HTML template. - Ensure you are querying with
sdk.root.querySelector(...), notdocument.querySelector(...). Your widget lives in a Shadow DOM.
Styles don't apply
- Styles in your widget HTML template are automatically scoped to the Shadow DOM by the platform.
- External stylesheets work but must be referenced from within your template.
- Host page styles do not penetrate the Shadow DOM (this is by design).
Props are empty or undefined
- Check that the widget's configuration contains valid JSON.
- Props are read at call time — call
sdk.getProps()when you need the current values.
Widget doesn't clean up properly
- Ensure you subscribe to
sdk.on('destroy', ...)in yourinitfunction and tear down your UI framework. - If using intervals or event listeners, clean them up in the destroy handler.
Module import errors
- Verify your widget is bundled as an ES module (
format: 'es'in your build config). - If using a framework (React, Vue, etc.), ensure it is bundled into your widget output — the platform does not provide frameworks.
Getting Help
If you can't resolve your issue:
Gather information:
- Error code and message (screenshots help)
- Steps to reproduce
- Browser and OS version
- Organization name (if applicable)
Check documentation:
- Widget Runtime — How widgets work at runtime
- Connect Your GitHub Account
- Repository & Branch Settings
- Build & Publish
- Admin Approval
Talk to your Gainsight team:
- Provide the gathered information
- Include relevant build IDs or timestamps
- Describe what you've already tried
Quick Reference
| Symptom | First Check | Guide |
|---|---|---|
| Can't find organization | GitHub membership | Connect Your GitHub Account |
| Repository not visible | App permissions | Repository Settings |
| Installation suspended | Org admin / GitHub status | This guide |
| Widget not updating | Watched branch | Build & Publish |
| Build failing | Error messages | This guide |
| Need admin approval | Enterprise policies | Admin Approval |
| Static widget errors | Error code | Error Codes |
| Widget stuck on "Loading..." | Shadow DOM query | Rendering & DOM |
| Only one instance updates | querySelector vs querySelectorAll | Rendering & DOM |
| Widget renders nothing / styles broken | Shadow DOM, mount point | This guide (Widget Development) |
Next Steps
- Error Codes — Full error code reference with causes and fixes
- Build & Publish — Understand the push-to-publish pipeline
- Content Security — Learn about content scanning and security policies

