URLs with redundant slashes cause Unpoly to trigger a `DOMException` · Issue #612 · unpoly/unpoly · GitHub
Skip to content

URLs with redundant slashes cause Unpoly to trigger a DOMException #612

Open

Description

@makmic

Bug description

While testing an application which was using Unpoly, I noticed that the Cookie Banner was somehow not working at all.
The culprit however was the JavaScript exception within Unpoly's source code:

Uncaught DOMException: Failed to execute 'replaceState' on 'History': A history state object with URL 'http://en/sign-in' cannot be created in a document with origin 'http://foobar.lvh.me:3000' and URL 'http://foobar.lvh.me:3000//en/sign-in'.

Due to a copy&paste mistake I was accessing the page at http://foobar.lvh.me:3000//en/sign-in' (two forward slashes) instead of http://foobar.lvh.me:3000/en/sign-in'. That's a niche case, but as the application renders fine in this case I'd except Unpoly not to crash too.

Steps to reproduce the behavior:

  1. Go to https://unpoly.com//install
  2. See the following error in the console:
Uncaught DOMException: Failed to execute 'replaceState' on 'History': A history state object with URL 'https://install/' cannot be created in a document with origin 'https://unpoly.com' and URL 'https://unpoly.com//install'.

Browser version

  • OS: Linux
  • Browser Chrome
  • Version 124

Activity

  1. adam12 commented on May 8, 2024

    @adam12
    Member

    Thanks for the report. I see the same on Safari + MacOS.

  2. hiSandog commented on Jun 29, 2026

    @hiSandog

    Reproduced this at https://unpoly.com//install too — the doubled slash makes the browser treat the target as a protocol-relative/cross-origin URL, so history.replaceState throws DOMException. A cheap fix would be to normalize consecutive slashes (or at least strip a leading // after the origin) before any replaceState/pushState call in the navigation layer. Even without full normalization, guarding the history call so a malformed URL degrades to a plain navigation instead of crashing would prevent the hard failure. Happy to trace where the URL gets handed to history if a pointer helps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions