#1834·puck

AutoField unconditionally overrides custom id prop instead of falling back like AutoFieldInternal

Author: DamianKocjanCreated Sep 9, 2026Updated Sep 17, 2026
Labelstype: bug 🐛in triage

Description

FieldProps defines an optional id?: string prop for fields. However, <AutoField /> unconditionally generates a new ID with const id = useSafeId() and passes id={id} after {...props}, overriding any custom id supplied by the caller.

In contrast, AutoFieldInternal respects an existing id prop with fallback:

typescript
const { id, Label = FieldLabelInternal } = props;
const defaultId = useSafeId();
const resolvedId = id || defaultId;

Because fields like ArrayField and ObjectField now read their state from fieldStore using name (which defaults to id), AutoField needs the store key in <fieldContextStore.Provider value={{ [id]: props.value }}> to match the id passed to <AutoFieldPublicInternal />. However, doing const id = props.id || useSafeId() would keep fieldContextStore and child fields in sync while still allowing custom IDs to be preserved.

Is there a specific reason why AutoField overrides potential incoming IDs rather than resolving them with a fallback like AutoFieldInternal?

Environment

  • Puck version: since 0.21.0

Steps to reproduce

  1. Render an <AutoField /> and pass an explicit id:
typescript
<AutoField
  field={{
    type: "text",
    label: "Custom Field",
  }}
  value={value}
  onChange={setValue}
  id="my-custom-id"
/>
  1. Inspect the rendered DOM elements or field store key.

What happens

The provided id="my-custom-id" is completely ignored.

In packages/core/components/AutoField/index.tsx:

typescript
export function AutoField<
  ValueType = any,
  FieldType extends FieldNoLabel<ValueType> = FieldNoLabel<ValueType>
>(props: FieldProps<FieldType, ValueType> & { value: any }) {
  const id = useSafeId();

  if (props.field.type === "slot") {
    return null;
  }

  return (
    <fieldContextStore.Provider value={{ [id]: props.value }}>
      <AutoFieldPublicInternal<ValueType, FieldType> {...props} id={id} />
    </fieldContextStore.Provider>
  );
}

Because id={id} is spread after {...props}, the newly generated useSafeId() always clobbers props.id.

What I expect to happen

AutoField should honor props.id when provided, falling back to useSafeId() only if props.id is undefined.

Additional Media

ImageImage