Skip to content

Optional url field cannot be cleared in the admin: empty value rejected as invalid URL #4075

Closed

Description

@marcin-misiewicz-pl

Bug

A non-required url field cannot be cleared from the admin. Emptying the input and saving the entry fails with the URL validation error ("URL must use http, https, mailto, or tel, or be a site-relative path" / the localized "valid URL" message), so once a url field has a value, an editor can never remove it.

Steps to reproduce

  1. Add an optional (not required) field of type url to a collection.
  2. Save an entry with a value in it, e.g. https://example.com.
  3. Clear the input in the entry editor and save.

Expected: the entry saves with the field empty (null), like any other optional field.
Actual: the save is rejected with the URL format error.

Cause

  • The admin's UrlFieldEditor passes the raw input value to onChange, so a cleared field is sent as "", not null.
  • getBaseSchema("url") in packages/core/src/schema/zod-generator.ts runs isSafeUrlFieldValue(ctx.value) on every string. "" is neither an absolute URL nor a site-relative path, so it fails. .nullish() for non-required fields accepts null/undefined but not "".

This seems to have come in with the safe-scheme restriction for url fields (#3327). #3791 fixed the same class of problem for number fields ("save a cleared number field as empty"). The same treatment for url would fix this: send null for a cleared url input, or accept "" as empty for a non-required url field.

Environment

  • emdash / @emdash-cms/admin 1.2.0 (also present on main as of 2026-10-09)
  • Cloudflare Workers + D1

Activity

  1. emdashbot commented on Oct 9, 2026

    @emdashbot
    Contributor

    Completed

    Optional url field cannot be cleared in the admin: empty value rejected as invalid URL

    • Review the issue and relevant repository context

    Outcome: Reproduced cause. The admin's UrlFieldEditor in packages/admin/src/components/ContentEditor.tsx passes the raw input string to onChange, so clearing a non-required url field sends "" instead of null. The Zod base schema for url in packages/core/src/schema/zod-generator.ts always runs isSafeUrlFieldValue(ctx.value) on strings, and "" fails validation because it is neither a safe absolute URL nor a site-relative path. Non-required fields only mark the schema .nullish(), which accepts null/undefined but not "". This matches the previously fixed number-field issue (#3791), where onChange was changed to send null when the input is empty. Safe fix: mirror that treatment in UrlFieldEditor so a cleared optional URL is sent as null (or, alternatively, treat "" as empty in the base schema before validation). No product, security, migration, or dependency decision is needed.

    Mode: triage

    View live dashboard · Run: b9abb4f7-88aa-4136-ba37-651800b4a502

  2. emdashbot commented on Oct 9, 2026

    @emdashbot
    Contributor

    Completed

    Fix optional URL field clearing in admin by sending null for empty values, matching the number-field fix pattern.

    • Locate UrlFieldEditor and URL schema validation code
    • Create a failing regression test for cleared optional URL
    • Update UrlFieldEditor to emit null for empty input
    • Run focused tests, format, lint, typecheck, build
    • Add changeset and publish candidate

    Outcome: Fixed the optional URL field clearing bug in the admin. The UrlFieldEditor now emits null for an empty input, mirroring the existing number-field behavior. A regression test was added and verified to fail before the fix and pass after. The full ContentEditor.test.tsx suite (154 tests) passes, and typecheck/build succeed. Note: pnpm lint:json (type-aware lint) could not complete in this environment due to resource limits (timeout/SIGKILL), but pnpm lint:quick returned zero diagnostics.

    Mode: work

    View live dashboard · Run: 421d90e7-6fce-4f2f-9e83-08562a7b4b0d

  3. emdashbot commented on Oct 9, 2026

    @emdashbot
    Contributor

    I opened PR #4076 with a candidate change.

    Fixed the optional URL field clearing bug in the admin. The UrlFieldEditor now emits null for an empty input, mirroring the existing number-field behavior. A regression test was added and verified to fail before the fix and pass after. The full ContentEditor.test.tsx suite (154 tests) passes, and typecheck/build succeed. Note: pnpm lint:json (type-aware lint) could not complete in this environment due to resource limits (timeout/SIGKILL), but pnpm lint:quick returned zero diagnostics.

    Try the change against your own site:

    npm i https://pkg.pr.new/emdash@bot/fix-4075

    Or try the candidate in a ready-to-use playground:

    Open the playground preview

    @marcin-misiewicz-pl could you try this? Reply naturally to say whether it works or explain what still needs to change.

    A maintainer reviews the pull request before merge; requested changes start another candidate revision.

    Fix branch: bot/fix-4075 · Artifacts branch: bot/artifacts-4075

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions