Skip to content

Conversation

@lilnasy
Copy link

@lilnasy lilnasy commented Oct 27, 2025

Before

docker run

   ╭───────────────────────────────────────────────────╮
   │                                                   │
   │                 Update available!                 │
   │                                                   │
   │                 11.10.2 → 11.12.0                 │
   │                 2 versions behind                 │
   │                                                   │
   │                 More information:                 │
   │   https://github.com/directus/directus/releases   │
   │                                                   │
   ╰───────────────────────────────────────────────────╯

file:///directus/node_modules/.pnpm/[email protected]/node_modules/zod/v4/core/schemas.js:865
    const first = def.options[0]._zod.run;
                                      ^

TypeError: Cannot read properties of undefined (reading 'run')
    at file:///directus/node_modules/.pnpm/[email protected]/node_modules/zod/v4/core/schemas.js:865:39
    at Function.init (file:///directus/node_modules/.pnpm/[email protected]/node_modules/zod/v4/core/core.js:14:9)
    at file:///directus/node_modules/.pnpm/[email protected]/node_modules/zod/v4/classic/schemas.js:544:20
    at Function.init (file:///directus/node_modules/.pnpm/[email protected]/node_modules/zod/v4/core/core.js:14:9)
    at file:///directus/node_modules/.pnpm/[email protected]/node_modules/zod/v4/classic/schemas.js:556:14
    at init (file:///directus/node_modules/.pnpm/[email protected]/node_modules/zod/v4/core/core.js:14:9)
    at new ZodDiscriminatedUnion (file:///directus/node_modules/.pnpm/[email protected]/node_modules/zod/v4/core/core.js:31:9)
    at Module.discriminatedUnion (file:///directus/node_modules/.pnpm/[email protected]/node_modules/zod/v4/classic/schemas.js:561:12)
    at file:///directus/node_modules/.pnpm/@directus+api@file+api_@[email protected][email protected]/node_modules/@directus/api/dist/websocket/messages.js:4:36
    at ModuleJob.run (node:internal/modules/esm/module_job:343:25)

Node.js v22.18.0

After (see "Loaded extensions")

docker run

   ╭───────────────────────────────────────────────────╮
   │                                                   │
   │                 Update available!                 │
   │                                                   │
   │                 11.10.2 → 11.12.0                 │
   │                 2 versions behind                 │
   │                                                   │
   │                 More information:                 │
   │   https://github.com/directus/directus/releases   │
   │                                                   │
   ╰───────────────────────────────────────────────────╯

[11:25:52.506] INFO: Initializing bootstrap...
[11:25:52.512] INFO: Installing Directus system tables...
[11:25:52.590] INFO: Running migrations...
[91 more lines]
[11:25:54.367] INFO: Setting up first admin role...
[11:25:54.385] INFO: Adding first admin user...
[11:25:54.386] INFO: No admin email provided. Defaulting to "[email protected]"
[11:25:54.386] INFO: No admin password provided. Defaulting to "15oBBetWMuuJ"
[11:25:54.434] INFO: Done
2025-10-27T11:25:54: PM2 log: Launching in no daemon mode
2025-10-27T11:25:54: PM2 log: App [directus:0] starting in -cluster mode-
   ╭───────────────────────────────────────────────────╮
   │                                                   │
   │                 Update available!                 │
   │                                                   │
   │                 11.10.2 → 11.12.0                 │
   │                 2 versions behind                 │
   │                                                   │
   │                 More information:                 │
   │   https://github.com/directus/directus/releases   │
   │                                                   │
   ╰───────────────────────────────────────────────────╯
2025-10-27T11:25:57: PM2 log: App [directus:0] online
[11:26:01.105] INFO: Extensions loaded
[11:26:01.110] INFO: Loaded extensions: @directus-labs/collaborative-editing, @directus-labs/command-palette-module
[11:26:01.119] WARN: "SECRET" env variable is missing. Using a random value instead. Tokens will not persist between restarts. This is not appropriate for production usage.
[11:26:01.120] WARN: "PUBLIC_URL" should be a full URL
[11:26:01.121] WARN: Spatialite isn't installed. Geometry type support will be limited.
[11:26:01.225] INFO: Server started at http://0.0.0.0:8055


switch (issue.code) {
case 'invalid_enum_value':
case 'invalid_value':
Copy link
Author

Choose a reason for hiding this comment

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

z.ZodInvalidEnumValueIssue has merged with ZodIssueInvalidValue

Comment on lines -17 to +18
valid = issue.options;
valid = issue.values;
Copy link
Author

Choose a reason for hiding this comment

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

.values contains the list of acceptable literals in the case of validating against an enum.

Comment on lines -19 to +20
case 'invalid_string':
case 'invalid_format':
Copy link
Author

Choose a reason for hiding this comment

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

z.ZodInvalidStringIssue was renamed to ZodIssueInvalidStringFormat.

interface: 'toggle',
width: 'half',
note: 'Hide the current user\'s avatar from collaborative editing indicators',
note: "Hide the current user's avatar from collaborative editing indicators",
Copy link
Author

Choose a reason for hiding this comment

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

This is the result of manually running prettier. I noticed eslint and prettier don't automatically run, but I didn't make any changes there to keep this PR simple and easy to review. I could hook it up in a separate PR.

"vue-router": "4.5.0"
"vue-i18n": "11.1.1",
"vue-router": "4.5.0",
"zod": "^4.0.14"
Copy link
Author

Choose a reason for hiding this comment

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

4.0.14 is the exact version @directus/api, @directus/extensions, and @directus/extensions-registry currently use. If they update, as long as it is a pathc or minor update, the extension will install without errors.

thumbnailField: z.string().optional().nullable(),
fields: z.array(z.string().min(1, 'field name cannot be empty')),
filter: z.object({}).optional().nullable() as z.ZodType<Filter | undefined>,
filter: z.object({}).optional().nullable() as z.ZodNullable<z.ZodOptional<z.ZodType<Filter>>>,
Copy link
Author

Choose a reason for hiding this comment

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

This is not directly related to the upgrade, but it was causing a type error insystem-colelctions.ts, requiring it explicitly set the filter field to undefined.

collections: z.array(SearchCollection),
triggerRate: z.number().gte(0, 'greater than or equal to 0').optional(),
commandPaletteEnabled: z.boolean().optional().default(true),
recentSearchLimit: z.number().gte(0, 'greater than or equal to 0').optional(),
Copy link
Author

Choose a reason for hiding this comment

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

This field is used by useRecentCommands() to control how many recent commands are shown at most. Was not present in the schema before.

},
"scripts": {
"build": "directus-extension build",
"check": "vue-tsc --noEmit",
Copy link
Author

Choose a reason for hiding this comment

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

I used vue-tsc to check for any type errors during migrations as some interfaces were authored inside vue modules. There are several unrelated type errors, so this command is not automatically run in CI, though I think it eventually should. I could open a PR for it separately.

"compilerOptions": {
"target": "ES2019",
"lib": ["ES2019", "DOM"],
"lib": ["ES2021", "DOM"],
Copy link
Author

Choose a reason for hiding this comment

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

The extension included uses of String#replaceAll() which is an ES2021 feature.

"lib": ["ES2021", "DOM"],
"rootDir": "./src",
"moduleResolution": "node",
"moduleResolution": "bundler",
Copy link
Author

@lilnasy lilnasy Oct 27, 2025

Choose a reason for hiding this comment

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

"node" (renamed to "node10" then removed from recent versions of typescript) module resolution does not pick up on ESM packages, which some Directus packages from the main repo have upgraded to. "node16" is an alternative that disallows extension-less imports.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR migrates the codebase from Zod v3 to v4 to maintain compatibility with Directus 11.10.2+, which upgraded to Zod v4. The migration addresses breaking API changes in Zod v4's validation schema structure and error handling.

Key Changes:

  • Updated Zod API calls to match v4 syntax (invalid_enum_valueinvalid_value, errorMaperror, etc.)
  • Moved Zod from dependencies to peerDependencies to ensure version compatibility with Directus
  • Updated TypeScript configuration to support Zod v4's module resolution requirements

Reviewed Changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated no comments.

Show a summary per file
File Description
packages/command-palette-module/tsconfig.json Updated lib and moduleResolution for Zod v4 compatibility
packages/command-palette-module/src/utils/errors.ts Migrated error handling from v3 (invalid_enum_value, options) to v4 (invalid_value, values)
packages/command-palette-module/src/types.ts Updated Zod schema syntax: errorMaperror, type casting for nullable/optional, added recentSearchLimit
packages/command-palette-module/package.json Moved zod to peerDependencies, added vue-tsc for type checking
packages/collaborative-editing/src/module/utils/errors.ts Migrated error handling to Zod v4 API
packages/collaborative-editing/src/module/settings-fields.ts Fixed quote escaping in string
packages/collaborative-editing/package.json Moved zod to devDependencies, reordered dependencies alphabetically
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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

Labels

None yet

Projects

None yet

2 participants