mastra-ai/mastra · error · Error

useJSONSchemaFormField must be used within a JSONSchemaForm.

Error message

useJSONSchemaFormField must be used within a JSONSchemaForm.Field

What it means

useJSONSchemaFormField exposes the enclosing field's value and mutators (field, update, remove, parentPath, depth) from JSONSchemaFormFieldContext provided by JSONSchemaForm.Field. Outside a Field the context is null and the hook throws, since per-field controls are meaningless without their field scope.

Source

Thrown at packages/playground-ui/src/ds/components/JSONSchemaForm/json-schema-form-field-context.tsx:27

  remove: () => void;
}

const JSONSchemaFormFieldContext = React.createContext<JSONSchemaFormFieldContextValue | null>(null);

export function JSONSchemaFormFieldProvider({
  children,
  value,
}: {
  children: React.ReactNode;
  value: JSONSchemaFormFieldContextValue;
}) {
  return <JSONSchemaFormFieldContext.Provider value={value}>{children}</JSONSchemaFormFieldContext.Provider>;
}

export function useJSONSchemaFormField(): JSONSchemaFormFieldContextValue {
  const context = React.useContext(JSONSchemaFormFieldContext);
  if (!context) {
    throw new Error('useJSONSchemaFormField must be used within a JSONSchemaForm.Field');
  }
  return context;
}

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Place the consumer inside <JSONSchemaForm.Field name={...}>...</JSONSchemaForm.Field>.
  2. If the control needs sibling-level access, pass field/update/remove as props instead of using the hook.
  3. Keep Root > Field > control nesting intact when refactoring layout (Root alone is not enough — this hook needs Field context specifically).
  4. Distinguish the two hooks: use useJSONSchemaForm (Root-level) for form-wide operations, useJSONSchemaFormField only inside a Field.

Example fix

// before
<Root>
  <RemoveFieldButton /> {/* needs Field context */}
</Root>
// after
<Root>
  <Field name="title">
    <RemoveFieldButton />
  </Field>
</Root>
Defensive patterns

Strategy: try-catch

Validate before calling

// Confirm the consumer is inside a JSONSchemaForm.Field, not just Root:
// <Root><Field name="title"><MyControl/></Field></Root>
const ctx = React.useContext(JSONSchemaFormFieldContext);
if (!ctx) console.warn('Field-level control must be inside JSONSchemaForm.Field');

Type guard

function hasFieldContext(c: JSONSchemaFormFieldContextValue | null): c is JSONSchemaFormFieldContextValue {
  return c !== null;
}

Try / catch

// Hooks can't be caught; guard with an error boundary:
<ErrorBoundary fallback={<FieldControlsRequireField /> }>
  <RemoveFieldButton />
</ErrorBoundary>

Prevention

When it happens

Trigger: Rendering a field-level control (update/remove buttons, nested field widgets) outside <JSONSchemaForm.Field>; placing such a control directly under Root but not inside any Field; nesting mistakes where a widget intended for a Field is used in the Root's direct children.

Common situations: Custom delete/update buttons for a property moved outside the Field wrapper; reusing a field widget inside a different form abstraction that doesn't create Field context; conditional layouts that render the control one level too high in the tree.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/ccdbc145e6aa7c9a. Report an issue: GitHub.