databuddy-analytics / databuddy-analytics/Databuddy

SDK tracking ID helpers throw when Web Storage is unavailable

Open Beginner friendly
#638 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
1.2k
Forks
216
Avg merge
14h 53m
Merged PRs (30d)
154

Description

Describe the bug

The public SDK helpers getAnonymousId() and getSessionId() read from localStorage and sessionStorage without handling storage access errors.

Web Storage access can throw a DOMException such as SecurityError when storage is restricted by browser settings or unavailable in a sandboxed context. When this happens, these helpers throw instead of treating the tracking ID as unavailable.

The error also propagates through:

  • getTrackingIds()
  • getTrackingParams()

This differs from getProfileId(), which already catches storage errors and returns null.

This can affect user-facing flows that treat tracking information as optional metadata. For example, Stripe checkout metadata and contact-form submission both call getTrackingIds().

To Reproduce

  1. Load @databuddy/sdk in a browser.
  2. Override storage reads to simulate a restricted-storage environment:
const originalGetItem = Storage.prototype.getItem;

Storage.prototype.getItem = function () {
	throw new DOMException("Access is denied", "SecurityError");
};

try {
	getAnonymousId();
} finally {
	Storage.prototype.getItem = originalGetItem;
}
  1. Observe that getAnonymousId() throws SecurityError.

The same behavior occurs when getSessionId() encounters an inaccessible sessionStorage. The exception also propagates from getTrackingIds() and getTrackingParams().

Expected behavior

Storage access failures should be treated as missing tracking IDs:

getAnonymousId(); // null
getSessionId(); // null
getTrackingIds(); // { anonId: null, sessionId: null }
getTrackingParams(); // ""

If only one storage mechanism is unavailable, getTrackingIds() and getTrackingParams() should preserve the ID available from the other mechanism.

Explicit URLSearchParams values should continue to take priority without accessing the corresponding storage mechanism.

Screenshots

Not applicable. The failure is a thrown DOMException.

Environment (please complete the following information):

  • OS: windows 11
  • Browser: firefox
  • Version: 154.0
  • SDK version: @databuddy/sdk 2.6.0

Additional context

The affected code is in packages/sdk/src/core/tracker.ts.

Existing tests cover empty storage, populated storage, and URL-parameter precedence, but do not cover storage reads throwing.

A fix could follow the existing getProfileId() pattern by catching errors around each individual storage read and returning null.

AI usage disclosure

This issue report was drafted with OpenAI Codex. Codex inspected the affected SDK implementation, its call sites, existing tests, repository history, contribution guidelines, and AI usage policy. I personally reviewed and edited the report and reproduced the behavior before submission.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in packages/sdk/src/core/tracker.ts by reading getAnonymousId(), getSessionId(), getTrackingIds(), getTrackingParams(), and the existing getProfileId() handling. Run the existing SDK tests for storage and URL-parameter precedence, then add coverage for storage reads that throw. Done means unavailable storage returns null or an empty string while an available storage ID and explicit URLSearchParams values are preserved.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
frontend, web-dev
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.