Missing Data
Why Coframe events or conversions might not appear — and how to fix it
Copy this guide and your current settings as a prompt for your AI agent.
Preview agent promptSee the guide, code and settings included when you copy.
This page covers situations where Coframe analytics data is absent or incomplete even though the SDK appears to be loaded. Each section describes a specific, grounded cause, what symptom it produces, and how to resolve it.
If you have not yet verified that the SDK is loading correctly, start with Testing and Validation.
On this page
01Cookie consent not granted
Symptom: Events are never sent. The page loads and the SDK initialises normally, but no data appears in your analytics platform or experiment results — and the problem affects all visitors uniformly.
Cause: When waitForCookiesEnabled: true is set in the SDK configuration,
Coframe delays both cookie writes and event sending until { cookiesEnabled: true }
is pushed to window.CFQ. If your consent management platform never pushes
that command — because the visitor dismissed the consent banner without
accepting, or because the CMP integration is misconfigured — the gate remains
closed for the entire session and no events are sent.
Fix: Confirm that your CMP pushes { cookiesEnabled: true } in the
accept/allow callback:
// Call this from your CMP "cookies accepted" handler
window.CFQ = window.CFQ || [];
window.CFQ.push({ cookiesEnabled: true });You can check the current gate state in the browser console:
window.Coframe.debug.shouldSendEvents()If this returns false, consent has not been granted in this session.
If you need the treatmentApplied callback to fire before the visitor accepts
cookies — for example, to register experiment assignments with a consent-aware
analytics platform — use bulkCallbackV2WithoutConsent instead of
bulkCallbackV2. This variant fires regardless of cookie consent state:
window.CFQ = window.CFQ || [];
window.CFQ.push({
subscribe: 'treatmentApplied',
bulkCallbackV2WithoutConsent: (treatments, rawIds) => {
// fires even before cookiesEnabled is pushed
treatments.forEach(t => console.log(t));
}
});See Tracking Settings for the full consent integration pattern.
02Events batched but not yet flushed
Symptom: Data appears eventually but with a noticeable delay, or short sessions (page refreshes, rapid navigation) produce fewer events than expected.
Cause: The SDK batches events before sending them to avoid a large number
of small requests. The default batchSize is 32 — events accumulate in
memory until 32 have queued up, at which point the SDK flushes the batch.
On low-traffic pages, or when a visitor leaves before a full batch has
accumulated, queued events may not be sent before the page unloads.
Fix: To confirm this is the issue, inspect the pending queue in the console and flush it manually:
// See what is currently queued
window.Coframe.debug.queuedEvents
// Force an immediate flush
window.Coframe.debug.flushQueuedEvents()To reduce the batch size globally so that events flush more frequently, set
batchSize in your SDK configuration:
<script>
window.CFQ = window.CFQ || [];
window.CFQ.push({
config: {
projectId: 'proj_abc123',
batchSize: 1
}
});
</script>A batchSize of 1 causes each event to be sent immediately. Use this during
development and QA; restore the default in production unless you have a specific
need to reduce latency.
03Conversion command missing metricId or metricName
Symptom: A specific conversion metric shows no data. Other events appear
normally. In window.Coframe.debug.logs, you may see an error logged by the
SDK.
Cause: The SDK validates every conversion command before recording it.
If the payload does not include at least one of metricId or metricName, the
SDK logs an error and discards the event — it is never queued or sent.
A common mistake is pushing a conversion command with only a value field,
or with a misspelled key:
// WRONG — neither metricId nor metricName present
window.CFQ.push({ conversion: { value: 99 } });
// WRONG — key is misspelled
window.CFQ.push({ conversion: { metric_name: 'purchase', value: 99 } });Fix: Include at least one of metricId or metricName:
window.CFQ = window.CFQ || [];
window.CFQ.push({
conversion: {
metricName: 'purchase_completed',
value: 99.99
}
});Or, using metricId:
window.CFQ.push({
conversion: {
metricId: 'metric_abc123',
value: 99.99
}
});Check window.Coframe.debug.logs immediately after the conversion fires to
see whether the SDK accepted or rejected the command.
See Tracking Settings for the conversion event reference.
04Session tested with ?cf_disabled
Symptom: A page that was recently tested shows no data for that session. The SDK behaves correctly for other visitors.
Cause: The installation snippet includes an early-exit guard: if the page
URL contains the string cf_disable, the SDK is never loaded. This is
commonly used to take baseline LCP measurements (see
Preview & Debugging), but any
session opened with ?cf_disabled or ?cf_disable in the URL produces no
Coframe events at all.
The guard is in the install-script IIFE and runs before the cf.js request is
even made, so the Network tab will show no cf.js request for these sessions.
Fix: Remove the cf_disable parameter before doing a test run you intend
to count. Then, on that clean session (where window.Coframe now exists), you
can confirm event sending is active with
window.Coframe.debug.shouldSendEvents() — it should return true.
05Preview mode suppresses events
Symptom: Events are missing only for sessions where a specific variant was forced via a URL parameter. Production traffic is unaffected.
Cause: When coframe_variant_id is present in the URL, the browser SDK
sets isPreviewVariant = true, which suppresses event sending. This is
intentional — preview sessions are for QA and should not pollute live
experiment data.
Fix: If you need to verify that analytics events fire correctly during a
preview session, add coframe_should_send_events=true to the URL:
https://yoursite.com/landing?coframe_variant_id=var_abc123&coframe_should_send_events=trueWith this parameter set, setForceSendEvents(true) is called during
resolveConfig, overriding the isPreviewVariant gate. Events sent this way
are delivered normally and will appear in your project’s event stream.
Confirm the gate is open by checking:
window.Coframe.debug.shouldSendEvents() // should return trueFor details on both preview parameters, see Preview & Debugging.
# Missing Data
Why Coframe events or conversions might not appear — and how to fix it
This page covers situations where Coframe analytics data is absent or
incomplete even though the SDK appears to be loaded. Each section describes a
specific, grounded cause, what symptom it produces, and how to resolve it.
If you have not yet verified that the SDK is loading correctly, start with
[Testing and Validation](../docs/testing-and-validation.html).
## Cookie consent not granted
Symptom: Events are never sent. The page loads and the SDK initialises
normally, but no data appears in your analytics platform or experiment results
— and the problem affects all visitors uniformly.
Cause: When `waitForCookiesEnabled: true` is set in the SDK configuration,
Coframe delays both cookie writes and event sending until `{ cookiesEnabled: true }`
is pushed to `window.CFQ`. If your consent management platform never pushes
that command — because the visitor dismissed the consent banner without
accepting, or because the CMP integration is misconfigured — the gate remains
closed for the entire session and no events are sent.
Fix: Confirm that your CMP pushes `{ cookiesEnabled: true }` in the
accept/allow callback:
JS
```
// Call this from your CMP "cookies accepted" handler
window.CFQ = window.CFQ || [];
window.CFQ.push({ cookiesEnabled: true });
```
You can check the current gate state in the browser console:
JS
```
window.Coframe.debug.shouldSendEvents()
```
If this returns `false`, consent has not been granted in this session.
If you need the `treatmentApplied` callback to fire before the visitor accepts
cookies — for example, to register experiment assignments with a consent-aware
analytics platform — use `bulkCallbackV2WithoutConsent` instead of
`bulkCallbackV2`. This variant fires regardless of cookie consent state:
JS
```
window.CFQ = window.CFQ || [];
window.CFQ.push({
subscribe: 'treatmentApplied',
bulkCallbackV2WithoutConsent: (treatments, rawIds) => {
// fires even before cookiesEnabled is pushed
treatments.forEach(t => console.log(t));
}
});
```
See [Tracking Settings](../docs/tracking-settings.html) for the full
consent integration pattern.
## Events batched but not yet flushed
Symptom: Data appears eventually but with a noticeable delay, or short
sessions (page refreshes, rapid navigation) produce fewer events than expected.
Cause: The SDK batches events before sending them to avoid a large number
of small requests. The default `batchSize` is `32` — events accumulate in
memory until 32 have queued up, at which point the SDK flushes the batch.
On low-traffic pages, or when a visitor leaves before a full batch has
accumulated, queued events may not be sent before the page unloads.
Fix: To confirm this is the issue, inspect the pending queue in the
console and flush it manually:
JS
```
// See what is currently queued
window.Coframe.debug.queuedEvents
// Force an immediate flush
window.Coframe.debug.flushQueuedEvents()
```
To reduce the batch size globally so that events flush more frequently, set
`batchSize` in your SDK configuration:
HTML
```
<script>
window.CFQ = window.CFQ || [];
window.CFQ.push({
config: {
projectId: 'proj_abc123',
batchSize: 1
}
});
</script>
```
A `batchSize` of `1` causes each event to be sent immediately. Use this during
development and QA; restore the default in production unless you have a specific
need to reduce latency.
## Conversion command missing metricId or metricName
Symptom: A specific conversion metric shows no data. Other events appear
normally. In `window.Coframe.debug.logs`, you may see an error logged by the
SDK.
Cause: The SDK validates every `conversion` command before recording it.
If the payload does not include at least one of `metricId` or `metricName`, the
SDK logs an error and discards the event — it is never queued or sent.
A common mistake is pushing a `conversion` command with only a `value` field,
or with a misspelled key:
JS
```
// WRONG — neither metricId nor metricName present
window.CFQ.push({ conversion: { value: 99 } });
// WRONG — key is misspelled
window.CFQ.push({ conversion: { metric_name: 'purchase', value: 99 } });
```
Fix: Include at least one of `metricId` or `metricName`:
JS
```
window.CFQ = window.CFQ || [];
window.CFQ.push({
conversion: {
metricName: 'purchase_completed',
value: 99.99
}
});
```
Or, using `metricId`:
JS
```
window.CFQ.push({
conversion: {
metricId: 'metric_abc123',
value: 99.99
}
});
```
Check `window.Coframe.debug.logs` immediately after the conversion fires to
see whether the SDK accepted or rejected the command.
See [Tracking Settings](../docs/tracking-settings.html) for the
conversion event reference.
## Session tested with ?cf_disabled
Symptom: A page that was recently tested shows no data for that session.
The SDK behaves correctly for other visitors.
Cause: The installation snippet includes an early-exit guard: if the page
URL contains the string `cf_disable`, the SDK is never loaded. This is
commonly used to take baseline LCP measurements (see
[Preview & Debugging](../docs/preview-and-debug.html)), but any
session opened with `?cf_disabled` or `?cf_disable` in the URL produces no
Coframe events at all.
The guard is in the install-script IIFE and runs before the `cf.js` request is
even made, so the Network tab will show no `cf.js` request for these sessions.
Fix: Remove the `cf_disable` parameter before doing a test run you intend
to count. Then, on that clean session (where `window.Coframe` now exists), you
can confirm event sending is active with
`window.Coframe.debug.shouldSendEvents()` — it should return `true`.
## Preview mode suppresses events
Symptom: Events are missing only for sessions where a specific variant was
forced via a URL parameter. Production traffic is unaffected.
Cause: When `coframe_variant_id` is present in the URL, the browser SDK
sets `isPreviewVariant = true`, which suppresses event sending. This is
intentional — preview sessions are for QA and should not pollute live
experiment data.
Fix: If you need to verify that analytics events fire correctly during a
preview session, add `coframe_should_send_events=true` to the URL:
PLAINTEXT
```
https://yoursite.com/landing?coframe_variant_id=var_abc123&coframe_should_send_events=true
```
With this parameter set, `setForceSendEvents(true)` is called during
`resolveConfig`, overriding the `isPreviewVariant` gate. Events sent this way
are delivered normally and will appear in your project’s event stream.
Confirm the gate is open by checking:
JS
```
window.Coframe.debug.shouldSendEvents() // should return true
```
For details on both preview parameters, see
[Preview & Debugging](../docs/preview-and-debug.html).
## Related links
- [Configuration: Tracking Settings](../docs/tracking-settings.html) — conversion events, `batchSize`, consent integration
- [SDK Reference: Preview & Debugging](../docs/preview-and-debug.html) — `?cf_disabled`, `coframe_variant_id`, `coframe_should_send_events`
- [SDK Reference: CFQ Commands](../docs/cfq-commands.html) — full command reference including `cookiesEnabled` and `conversion`
- [Troubleshooting: Debug Checklist](../docs/debug-checklist.html) — step-by-step SDK diagnostic checklist
- [Troubleshooting: Data Verification](../docs/data-verification.html) — verifying that events reached the platform
- [Analytics: Events and Tracking](../docs/events-and-tracking.html) — event types and the analytics integration model