Skip to content

fix: invalid option error when modifying enums in docsSchema's extend - #3936

Merged
delucis merged 17 commits into
withastro:mainfrom
miichom:main
Jul 22, 2026
Merged

delucis merged 17 commits into
withastro:mainfrom
miichom:main

Conversation

@miichom

@miichom miichom commented May 31, 2026 •

Copy link
Copy Markdown
Contributor

Description

In the starlight docs, it mentions docsSchema() can modify fields, however it is unable to modify z.enum fields The likely cause is from how ZodIntersection are treated.

Why this happens

The Zod documentation explicitly notes that intersections (a logical "AND") produce a ZodIntersection instance rather than a ZodObject.

From the Zod v4 docs:

When merging object schemas, prefer A.extend(B) over intersections. Using .extend() will give you a new object schema, whereas z.intersection(A, B) returns a ZodIntersection instance which lacks common object methods like pick and omit.

This limitation also affects any tooling that expects to operate on a ZodObject, including schema‑amending utilities like docsSchema().

@changeset-bot

changeset-bot Bot commented May 31, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: d68cb43

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@astrojs/starlight Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@netlify

netlify Bot commented May 31, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for astro-starlight ready!

Name Link
🔨 Latest commit d68cb43
🔍 Latest deploy log https://app.netlify.com/projects/astro-starlight/deploys/6a60cd34d7b7fb0008b6940e
😎 Deploy Preview https://deploy-preview-3936--astro-starlight.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
Lighthouse
Lighthouse
1 paths audited
Performance: 100 (no change from production)
Accessibility: 100 (no change from production)
Best Practices: 100 (no change from production)
SEO: 100 (no change from production)
PWA: -
View the detailed breakdown and full score reports
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@github-actions github-actions Bot added the 🌟 core Changes to Starlight’s main package label May 31, 2026
@astrobot-houston

Copy link
Copy Markdown
Contributor

Hello! Thank you for opening your first PR to Starlight! ✨

Here’s what will happen next:

  1. Our GitHub bots will run to check your changes.
    If they spot any issues you will see some error messages on this PR.
    Don’t hesitate to ask any questions if you’re not sure what these mean!

  2. In a few minutes, you’ll be able to see a preview of your changes on Netlify 🤩

  3. One or more of our maintainers will take a look and may ask you to make changes.
    We try to be responsive, but don’t worry if this takes a few days.

@delucis delucis left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR @miichom! And apologies for the slow response — I knew this would be a tricky one and needed time to play around with it to be sure the fix would work.

I’ve pushed up some tests for schema extension — previously we only touched that logic very minimally in an unrelated test. I included one for your case of extending a z.enum() property, which now passes on this branch (running that test against main fails, as you reported in #3935). However, the second part of this is type testing: this helps us ensure that the types inferred from an extended docs schema are correct.

Your changes seem to introduce an issue with the types when extending an object, e.g.

docsSchema({
	extend: z.object({ sidebar: z.object({ custom: z.number() }) }),
})

The default properties of the sidebar field are missing, with only the custom extension present. AFAICT this issue only impacts the types — you can see that in the failing test in CI. At runtime, all properties are parsed by Zod as expected.

Would you be able to take a look?

@HiDeoo

HiDeoo commented Jul 3, 2026

Copy link
Copy Markdown
Member

Your changes seem to introduce an issue with the types when extending an object, e.g.

Just to make sure, is only the type check an issue? Is this snapshot correct here and the result with sidebar default properties being dropped is expected?

@delucis

delucis commented Jul 3, 2026 •

Copy link
Copy Markdown
Member

Is this snapshot correct here and the result with sidebar default properties being dropped is expected?

Oh damn, you’re 100% correct. I thought I remembered checking this and seeing that everything expected was there, but nope, they’re dropped. So, yes, the issue is present for both runtime values AND types.

I updated that snapshot to reflect the runtime breakage too.

Comment thread packages/starlight/__tests__/basics/schema.test.ts
Comment thread packages/starlight/__tests__/basics/schema.test-d.ts
@HiDeoo

HiDeoo commented Jul 4, 2026 •

Copy link
Copy Markdown
Member

Played around with a potential fix in #4040.

I did that in a different PR to not mess around with the current PR where I cherry-picked all the commits from this PR in a single commit and added what I worked on top of it (also added 1 test and tweaked an existing one).

This is a draft as I'm not yet sure if this is the right approach or there are better ones, and I did not yet review it properly as I was so head down in the code that I did not yet take a step back. It's also overly commented as I was sometime getting lost when implementing it and I did not clean anything up yet.

If we ever decide to move forward with this, we should cherry pick only the relevant commits from #4040 in this PR so author credit is preserved and the history is cleaner.

@HiDeoo HiDeoo mentioned this pull request Jul 4, 2026
@miichom

miichom commented Jul 4, 2026

Copy link
Copy Markdown
Contributor Author

It's also overly commented as I was sometime getting lost when implementing it and I did not clean anything up yet.

I personally think for now keeping it commented is a good idea, I will have a proper look when I get home.

@miichom

miichom commented Jul 17, 2026

Copy link
Copy Markdown
Contributor Author

Okay, it took sometime but I preferred @HiDeoo schema merging over my one - I did remove the comments, but I am happy to re-add them if it helps others in the future. I added another test as the icon must start with <svg in the schema and would error without these PR changes.

@delucis delucis left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your patience on this one @miichom!

I think we’re happy to accept this change with HiDeoo’s implementation. I wonder if it would be good to move most of this new code into a file under packages/starlight/utils/ to help keep the main schema.ts file focused on its primary purpose of declaring the schema. What do you think?

@miichom

miichom commented Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

I think that is a great idea!

@delucis delucis left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @miichom — looking good! Just left a couple of last small notes.

Comment thread .changeset/all-badgers-grin.md Outdated
Comment thread packages/starlight/utils/zodDeepMerge.ts
delucis
delucis previously approved these changes Jul 22, 2026

@delucis delucis left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @miichom! I think this looks good to me. Will give @HiDeoo a chance to leave a final review in case he has time today, but otherwise we’ll get this released soon 🙌

@HiDeoo HiDeoo left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pushing this over the finish line and cleaning up the code. This looks perfect to me and ready to be shipped 🚀

One tiny nit: now that this new utility and associated type live in their dedicated file, maybe we should rename the exported function and type, e.g. deepMergeSchemas() and DeepMergedSchema so the intent when reading other files is clearer?

@miichom

miichom commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

One tiny nit: now that this new utility and associated type live in their dedicated file, maybe we should rename the exported function and type, e.g. deepMergeSchemas() and DeepMergedSchema so the intent when reading other files is clearer?

I am for this! It makes a little more sense than mergeWithDefaultSchema.

@delucis delucis left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks again @miichom and @HiDeoo for the collaboration on this one 🙌

@delucis
delucis merged commit 712eedd into withastro:main Jul 22, 2026
16 checks passed
@astrobot-houston astrobot-houston mentioned this pull request Jul 22, 2026
dadezzz pushed a commit to dadezzz/university_notes that referenced this pull request Jul 26, 2026
This PR contains the following updates:

| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [@astrojs/starlight](https://starlight.astro.build) ([source](https://github.com/withastro/starlight/tree/HEAD/packages/starlight)) | [`0.41.3` → `0.41.4`](https://renovatebot.com/diffs/npm/@astrojs%2fstarlight/0.41.3/0.41.4) | ![age](https://developer.mend.io/api/mc/badges/age/npm/@astrojs%2fstarlight/0.41.4?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@astrojs%2fstarlight/0.41.3/0.41.4?slim=true) |

---

### Release Notes

<details>
<summary>withastro/starlight (@&#8203;astrojs/starlight)</summary>

### [`v0.41.4`](https://github.com/withastro/starlight/blob/HEAD/packages/starlight/CHANGELOG.md#0414)

[Compare Source](https://github.com/withastro/starlight/compare/@astrojs/starlight@0.41.3...@astrojs/starlight@0.41.4)

##### Patch Changes

- [#&#8203;3936](withastro/starlight#3936) [`712eedd`](withastro/starlight@712eedd) Thanks [@&#8203;miichom](https://github.com/miichom)! - Fixes support for modifying Zod enums when passing an [`extend` option](https://starlight.astro.build/reference/frontmatter/#extend) to Starlight’s `docsSchema()`

- [#&#8203;4092](withastro/starlight#4092) [`0896b91`](withastro/starlight@0896b91) Thanks [@&#8203;delucis](https://github.com/delucis)! - Fixes support for links containing a protocol like `mailto:` in the sidebar

- [#&#8203;4088](withastro/starlight#4088) [`4486ba4`](withastro/starlight@4486ba4) Thanks [@&#8203;delucis](https://github.com/delucis)! - Simplifies Starlight’s client-side sidebar state persistence script slightly

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yNzIuNiIsInVwZGF0ZWRJblZlciI6IjQzLjI3Mi42IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->
maehr added a commit to textrefs/textrefs.org that referenced this pull request Jul 26, 2026
* chore(deps): upgrade to Astro 7.1, refresh dependencies (#39)

Move the site onto the Astro 7.1 line (7.0.6 -> 7.1.3) and refresh the
remaining dependencies. Backwards-compatible minor; all Starlight plugins
already declared support for astro >=7.

Starlight 0.41.4 replaced the intersection in docsSchema() with .extend()
so that enum fields can be modified (withastro/starlight#3936). The extend
option must now return a ZodObject, so src/content.config.ts composes the
blog schema with .extend() instead of .and(). Starlight deep-merges the
result, which keeps the UNSTABLE_BANNER default on the banner field.

TypeScript is held at ^6: @astrojs/check@0.9.9 peers ^5.0.0 || ^6.0.0.

Verified: npm run verify (format:check, astro check 0 errors, full build of
78940 pages), npm run validate:data (39250/39250 records), link check clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* chore(release): regenerate changelog with Astro 7.1

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Moritz Mähr <14755525+maehr@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🌟 core Changes to Starlight’s main package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

**hero.actions.1.variant**: Invalid option: expected one of "primary"|"secondary"|"minimal"

4 participants