Troubleshooting
Start with BabelShield.diagnose() for a snapshot of your integration status. Most issues can be identified from this
output alone.
Run Diagnostics First
Open your browser console and run:
BabelShield.diagnose();
This returns a diagnostic snapshot:
{
"version": "2.2.0",
"initialized": true,
"adapter": {
"name": "none",
"confidence": 0,
"version": null,
"allDetections": []
},
"forms": {
"total": 3,
"protected": 2,
"skipped": [
"#search-form (data-babel-shield-ignore)"
]
},
"config": {
"mode": "direct",
"failOpen": true,
"feedbackMode": "inline"
},
"environment": {
"url": "https://example.com/contact",
"hasJQuery": false,
"hasCKEditor": false
}
}
What Each Field Means
| Field | What to Check |
|---|---|
version |
Library version. Include this in support requests. |
initialized |
Should be true. If false, init failed or hasn't completed. |
adapter.name |
Active framework adapter: drupal, wordpress, or none (vanilla HTML). |
adapter.confidence |
Detection confidence (0-100). Low values suggest false detection. |
forms.total |
Total forms found on the page (protected + skipped). |
forms.protected |
Forms actively being moderated. |
forms.skipped |
Forms excluded and why (listed by selector or reason). |
config.mode |
direct (API calls from browser) or proxy (via backend). |
config.failOpen |
If true, forms submit normally when the API is unavailable. |
config.feedbackMode |
inline, modal, or silent. |
environment.hasJQuery |
Relevant for Drupal/WordPress AJAX form handling. |
environment.hasCKEditor |
If true, CKEditor content is extracted automatically. |
Enable Debug Mode
For detailed logging of every request, cache hit, and moderation result:
BabelShield.init({
apiToken: 'YOUR_API_TOKEN',
debug: true
});
Or via data attribute:
<script src="https://cdn.babelshield.ai/v1/babel-shield.js"
data-api-token="YOUR_API_TOKEN"
data-debug="true"></script>
Debug output appears in the browser console with the [BabelShield] prefix.
Common Issues
Cache Key Generation Errors
Symptom:
Error: Cache key generation failed. Ensure your app is served over HTTPS or use http://localhost for development.
Cause: The Web Crypto API requires a secure context -- HTTPS in production, or http://localhost /
http://127.0.0.1 in development. file:// URLs and non-localhost HTTP addresses do not work.
Solutions:
- Use
http://localhostfor local development - Use HTTPS in production (most hosting platforms provide free SSL)
- As a last resort, disable caching:
const result = await BabelShield.moderate(content, {
skipCache: true
});
Rate Limit Errors
Symptom:
RateLimitError: Client rate limit exceeded. Try again in 45s
Cause: Client-side rate limits exceeded -- 60 requests per minute or 1000 requests per hour. These limits reset on page reload.
Solutions:
- Batch content -- combine multiple fields into a single moderation request instead of moderating each field separately
- Use caching -- repeated calls with identical content use the cache (no API call)
- Check before sending:
if (BabelShield.isNearRateLimit()) {
// Show user a message or queue the request
return;
}
- Monitor usage:
const status = BabelShield.getRateLimitStatus();
console.log('Requests this minute:', status.used.minute);
console.log('Requests this hour:', status.used.hour);
Note: Server-side rate limits are separate and enforced by the API. For retry patterns with exponential backoff, see Error Handling.
CORS Errors
Direct API Mode
Symptom:
Access to fetch at 'https://api.babelshield.ai/...' from origin 'https://yoursite.com' has been blocked by CORS policy
Cause: Your domain is not authorized for the API token you're using.
Solutions:
- Check your Babel Shield dashboard -- ensure your domain is added to the token's allowed origins
- Verify the
apiUrlincludes the full path:
// Wrong
apiUrl: 'https://api.babelshield.ai'
// Correct
apiUrl: 'https://api.babelshield.ai/api/v1'
Proxy Mode
Cause: Your backend proxy endpoint needs CORS headers.
Solutions:
Add CORS headers to your proxy endpoint and handle preflight OPTIONS requests. For backend proxy configuration, see the API Reference.
Initialization Errors
"BabelShield is already initialized":
// Check before initializing
if (!BabelShield.isInitialized()) {
await BabelShield.init({apiToken: 'YOUR_API_TOKEN'});
}
// Or destroy before reinitializing
BabelShield.destroy();
await BabelShield.init({apiToken: 'NEW_TOKEN'});
"API client not initialized":
Wait for init() to complete before calling moderate():
const result = await BabelShield.init({apiToken: 'YOUR_API_TOKEN'});
if (result.success) {
await BabelShield.moderate(content);
}
"Invalid API token" or "Subscription required":
Verify your API token in the Babel Shield dashboard. Check that your subscription is active and the token hasn't been revoked.
Network and Timeout Errors
Timeout errors: Increase the timeout (maximum 60 seconds):
await BabelShield.init({
apiToken: 'YOUR_API_TOKEN',
timeout: 60000
});
The API client automatically retries on timeout, 429, 500, and 503 responses -- up to 2 retries with exponential backoff. Errors with status 400, 401, 403, and 422 are not retried.
Network errors: Check internet connectivity and verify the API is accessible.
Payload Validation Errors
"Payload cannot be null or undefined":
Validate content before calling moderate():
if (content != null && content !== '') {
await BabelShield.moderate(content);
}
"Payload must be JSON serializable":
The payload contains non-serializable values like circular references or BigInt values. Remove them before sending:
// Remove circular references by round-tripping through JSON
const safePayload = JSON.parse(JSON.stringify(rawPayload));
// Convert BigInt values to strings (JSON cannot serialize BigInt)
safePayload.value = bigIntValue.toString();
"Payload exceeds maximum size":
The payload is larger than 20KB when serialized. Truncate content or moderate in chunks:
const serialized = JSON.stringify(payload);
if (serialized.length > 20 * 1024 && typeof payload.text === 'string') {
payload.text = payload.text.substring(0, 10000);
}
Forms Not Being Protected
Symptom: Forms submit without moderation, no data-babel-shield-protected attribute added.
Solutions:
- Check initialization completed:
BabelShield.on('ready', () => {
console.log('Form handler should be active');
});
console.log('Initialized:', BabelShield.isInitialized());
console.log('Ready:', BabelShield.isReady());
- Check form selector matches:
const forms = document.querySelectorAll('form');
console.log('All forms:', forms.length);
const config = BabelShield.getConfig();
console.log('Forms selector:', config.forms);
console.log('Exclude selector:', config.excludeForms);
-
Check for ignore attribute -- remove
data-babel-shield-ignorefrom forms that should be protected. -
Manually attach a form:
const formHandler = BabelShield.getModule('form-handler');
const form = document.getElementById('my-form');
formHandler.attachForm(form);
Dynamic Forms Not Detected
Symptom: Forms added after page load are not protected.
Babel Shield uses a MutationObserver with a 50ms debounce to detect new forms. If forms are still not detected:
// Force re-scan after major DOM changes
const formHandler = BabelShield.getModule('form-handler');
formHandler.refresh();
// Or manually attach a specific form
const newForm = document.getElementById('dynamic-form');
formHandler.attachForm(newForm);
Field Content Not Being Moderated
Symptom: Specific field content is not included in the moderation payload.
Check field type exclusions. These fields are excluded by default:
type="password",type="hidden",type="file"-- not user contenttype="submit",type="button",type="reset",type="image"-- not content- Disabled or readonly fields
Check for ignore attribute:
<!-- This field is excluded -->
<input type="text"
name="code"
data-babel-shield-ignore>
Check contenteditable elements. They must have a name or data-name attribute:
<div contenteditable
data-name="rich-content">...
</div>
Modal Not Closing
Symptom: Modal feedback dialog does not close on button click or Escape key.
Check the browser console for JavaScript errors preventing event handlers from firing. To close the modal manually:
const formHandler = BabelShield.getModule('form-handler');
formHandler.ValidationUI.hideModal();
The modal uses focus trapping -- Tab cycles through elements inside the modal, and Escape should close it.
Custom Colors Not Working
Symptom: Severity colors do not match configuration.
- Check color format -- values must be valid CSS colors (hex, named, or RGB):
feedback: {
colors: {
low: '#ffc107',
medium: 'orange',
high: 'rgb(220, 53, 69)',
critical: '#721c24'
}
}
- Check CSS overrides -- external CSS might override custom properties:
:root {
--babel-shield-color-critical: red !important;
}
- Update colors at runtime:
const formHandler = BabelShield.getModule('form-handler');
formHandler.ValidationUI.setColors({
critical: '#ff0000'
});
Accessibility Issues
Symptom: Screen readers do not announce feedback, or keyboard navigation is broken.
Check that these ARIA attributes are present:
- Inline feedback should have
role="status" - Modal should have
role="dialog"andaria-modal="true" - Close button should be focusable
- Tab should cycle through modal elements (focus trapping)
- Escape should close the modal
Test with a screen reader (VoiceOver on Mac/iOS, NVDA or JAWS on Windows) to verify announcements.
Content Security Policy (CSP)
If your site uses a Content Security Policy, add the Babel Shield CDN and API domains:
Via meta tag:
<meta http-equiv="Content-Security-Policy"
content="default-src 'self';
script-src 'self' https://cdn.babelshield.ai;
connect-src 'self' https://api.babelshield.ai;
style-src 'self' 'unsafe-inline';">
Via HTTP header (preferred):
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.babelshield.ai; connect-src 'self' https://api.babelshield.ai;
unsafe-inline for style-src is needed because Babel Shield injects feedback styling. If your CSP blocks inline
styles, feedback messages may not display correctly.
Getting Help
If you're still experiencing issues:
- Check the browser console for detailed error messages
- Enable debug mode for additional logging
- Run
BabelShield.diagnose()and include the output in your support request - Check API status at status.babelshield.com
- Contact support with:
- Error message and stack trace
- Browser and version
- Babel Shield JS version (from
diagnose()output) - Steps to reproduce the issue
Next Steps
- Getting Started -- Verify your token and account setup
- API Reference -- Full endpoint documentation and error codes
- Vanilla HTML Quick Start -- Basic form protection setup
- WordPress Installation -- WordPress-specific integration
- Drupal Installation -- Drupal-specific integration