Skip to content

Admin: Reject non-primitive itemLabel property values#175

Merged
lehni merged 1 commit into
mainfrom
fix/item-label-non-string-property
Apr 29, 2026
Merged

Admin: Reject non-primitive itemLabel property values#175
lehni merged 1 commit into
mainfrom
fix/item-label-non-string-property

Conversation

@lehni
Copy link
Copy Markdown
Contributor

@lehni lehni commented Apr 29, 2026

Written by Claude.

getItemLabel (packages/admin/src/mixins/ItemMixin.js) has a property-key fallback that takes whatever item[key] returns:

const key = (
  isString(itemLabel) && itemLabel ||
  isListSource(sourceSchema) && columns && Object.keys(columns)[0] ||
  'name'
)
text = item[key]   // could be anything — array, object, function

The implicit contract is "produces a value usable as the label prop on DitoFormInner (typed String)", but nothing enforces it. If the property happens to hold an Array or Object — easy when the model property name and itemLabel collide — that flows into the Vue prop. Vue's prop validation then runs String(reactive proxy), throws Cannot convert object to primitive value, and the form render dies silently. Symptom we hit: e2e/assets/admin/upload.ts:29 'single file appears in table' reproduces the form mounting empty (<form><div class="dito-schema"><!--v-if--></div></form>).

Fix

Only accept string and number from the property lookup; otherwise fall through to the auto-generated label (index, etc.):

const value = item[key]
text = isString(value) || isNumber(value) ? value : null

Verified

The assets test schema uses itemLabel: 'files', which collides with AssetWidget.files. Before this PR, that produces a 100% reproducible failure on e2e/assets/admin/upload.ts:29. After this PR:

Test plan

  • Run pnpm --filter @ditojs/tests test:e2e — full suite green
  • Sanity-check existing admin scenarios that already use string-typed itemLabel properties — no behavior change expected

- getItemLabel returned item[key] without type check
- Array/object values flowed into DitoFormInner.label (typed String)
- Vue prop validation triggered String(reactive proxy) → render crash
- Restrict primitive lookup to string/number, fall through otherwise
@lehni lehni merged commit 099559a into main Apr 29, 2026
3 checks passed
@lehni lehni deleted the fix/item-label-non-string-property branch April 29, 2026 14:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant