-
Notifications
You must be signed in to change notification settings - Fork 626
Description
PLEASE NOTE: make sure the bug exists in the latest patch level of the project. For instance, if you are running a 2.x version of Apostrophe, you should use the latest in that major version to confirm the bug.
To Reproduce
Note: I used starter-kit-astro-essentials
Step by step instructions to reproduce the behavior:
- Create a new piece type
Articleinmodules/article/index.jsexport default { extend: '@apostrophecms/piece-type', options: { label: 'Article' }, fields: { add: { contactInfo: { label: 'Address', type: 'object', required: false, readOnly: true, fields: { add: { street: { type: 'array', label: 'Street', required: false, readOnly: true, // Can't see array items if it's read-only fields: { add: { type: { label: 'type', type: 'string', readOnly: true, required: false }, value: { label: 'value', type: 'string', readOnly: true, required: false } } } }, city: { type: 'string', label: 'City', required: false, readOnly: true }, state: { type: 'string', label: 'State', required: false, readOnly: true } } } } }, group: { basics: { label: 'Basics', fields: [ 'title', 'contactInfo' ] } } } };
- Enable the article module in
app.js - Create a new piece using the admin UI
- Run the following mongodb query
db.aposDocs.updateMany({type:'article'},{$unset:{contactInfo:1}})to delete thecontactInfofield. Why? The array/object field are read-only, not required and does not have a default value. You might have an external service creating article pieces using the Apostrophe API. - Using the admin UI, edit the existing article piece (you can update the
Visibilityfield) and try to save. - You should see the following error in the server console
article: api-error: Cannot read properties of undefined (reading 'street') { module: 'article', type: 'api-error', severity: 'error', url: '/api/v1/article/frvq49pb7vk93b200x5ireyk:en:draft?aposMode=draft&aposLocale=en', path: '/api/v1/article/frvq49pb7vk93b200x5ireyk:en:draft', method: 'PUT', ip: '::1', query: { aposMode: 'draft', aposLocale: 'en' }, requestId: 'stzkw3ycbben20mfclq2q53w', name: 'error', status: 500, stack: [ 'at Object.getNonVisibleFields (/srv/www/starter-kit-astro-essentials/backend/node_modules/apostrophe/modules/@apostrophecms/schema/index.js:716:48)', 'at process.processTicksAndRejections (node:internal/process/task_queues:103:5)', 'at async Object.getNonVisibleFields (/srv/www/starter-kit-astro-essentials/backend/node_modules/apostrophe/modules/@apostrophecms/schema/index.js:727:13)', 'at async Object.convert (/srv/www/starter-kit-astro-essentials/backend/node_modules/apostrophe/modules/@apostrophecms/schema/index.js:665:34)', 'at async Object.convert (/srv/www/starter-kit-astro-essentials/backend/node_modules/apostrophe/modules/@apostrophecms/doc-type/index.js:829:9)', 'at async /srv/www/starter-kit-astro-essentials/backend/node_modules/apostrophe/modules/@apostrophecms/piece-type/index.js:968:11', 'at async Object.withLock (/srv/www/starter-kit-astro-essentials/backend/node_modules/apostrophe/modules/@apostrophecms/lock/index.js:185:18)', 'at async /srv/www/starter-kit-astro-essentials/backend/node_modules/apostrophe/modules/@apostrophecms/module/index.js:193:30' ], cause: undefined, errorPath: undefined, data: {} }
Expected behavior
I should be able to save the updated piece without errors.
Describe the bug
One way to fix it can be to add some optional chaining in schema/index.js
diff --git a/packages/apostrophe/modules/@apostrophecms/schema/index.js b/packages/apostrophe/modules/@apostrophecms/schema/index.js
index f2d1ca922..7e3f5201e 100644
--- a/packages/apostrophe/modules/@apostrophecms/schema/index.js
+++ b/packages/apostrophe/modules/@apostrophecms/schema/index.js
@@ -713,7 +713,7 @@ module.exports = {
// Relationship does not support conditional fields right now
if ([ 'array' /*, 'relationship' */].includes(field.type) && field.schema) {
- for (const arrayItem of destination[field.name] || []) {
+ for (const arrayItem of destination?.[field.name] || []) {
await self.getNonVisibleFields({
req,
schema: field.schema,
@@ -727,7 +727,7 @@ module.exports = {
await self.getNonVisibleFields({
req,
schema: field.schema,
- destination: destination[field.name],
+ destination: destination?.[field.name],
nonVisibleFields,
fieldPath: curPath,
parentFollowingValuesIf we have an error on an invisible field, there is some logic to handle this in schema/index.js. I don't think the optional chaining solution covers all scenario.
const nonVisibleField = hiddenAncestors || nonVisibleFields.has(errorPath);
// We set default values only on final error fields
if (nonVisibleField && !error.data?.errors) {
const curSchema = self.getFieldLevelSchema(schema, error.schemaPath);
self.setDefaultToInvisibleField(curDestination, curSchema, error.path);
continue;
}Details
Version of Node.js:
PLEASE NOTE: Only stable LTS versions (10.x and 12.x) are fully supported but we will do our best with newer versions.
Node 24.13.1 + Npm 11.8.0
Server Operating System:
The server (which might be your dev laptop) on which Apostrophe is running. Linux? MacOS X? Windows? Is Docker involved?
Docker on MacOS (mongo:8.2.5 + node:24.13.1-alpine3.23)
Additional context:
Add any other context about the problem here. If the problem is specific to a browser, OS or mobile device, specify which.
/srv/www/starter-kit-astro-essentials/backend $ npm ls
starter-kit-astro@1.0.0 /srv/www/starter-kit-astro-essentials/backend
+-- @apostrophecms/blog@1.0.6
+-- @apostrophecms/vite@1.1.1
+-- apostrophe@4.27.0
+-- cross-env@10.1.0
+-- eslint-config-apostrophe@6.0.2
`-- nodemon@3.1.14
/srv/www/starter-kit-astro-essentials/frontend $ npm ls
astro-frontend@1.0.0 /srv/www/starter-kit-astro-essentials/frontend
+-- @apostrophecms/apostrophe-astro@1.9.0
+-- @astrojs/node@9.5.4
+-- astro@5.17.3
+-- cross-env@10.1.0
+-- dayjs@1.11.19
+-- postcss-viewport-to-container-toggle@1.1.0
`-- vite@7.3.1
Screenshots
If applicable, add screenshots to help explain your problem.