Skip to content

Form Context Not Propagating Through <form.AppForm> #1919

@aress31

Description

@aress31

Describe the bug

I have been reading the documentation and browsing issues here, but I still cannot determine whether this behaviour is a bug or an intentional design choice. <form.AppForm> does not appear to behave like a context provider at all, despite the expectation that it should.

Your minimal, reproducible example

N/A

Steps to reproduce

Consider the following simplified example:

function Root() {
  // --- SNIP ---
  const form = useAppForm({
    defaultValues: {
      foo: data?.foo ?? "",
      bar: "bar",
    } as ProviderInsertFormValues,
    onSubmit: async ({ value }) => {
      console.log(values);
    },
    validators: {
      onChange: ProviderInsertSchema,
    },
  });
  // --- SNIP ---

  return (
    <form.AppForm>
      <form onSubmit={form.handleSubmit}>
        <XFields />
      </form>
    </form.AppForm>
  );
}

Then in Child:

export default function Child() {
  const {
    Field,
    state: { isSubmitting },
  } = useFormContext();

  return (
    <FieldSet disabled={isSubmitting}>
      <Field name="apiKey">
        {(field) => (
          <field.InputAdornmentField
            label="Foo"
            placeholder="foo"
          />
        )}
      </Field>
    </FieldSet>
  );
}

I get several type errors, for example:

1. Error for the name key

Type 'string' is not assignable to type 'never'.ts(2322)
FieldApi.d.ts(136, 5): The expected type comes from property 'name' [...]

The error indicates that name resolves to never, as if the parent form has no recognised keys. This usually means the form context is not providing any type information down the tree.

2. Error for field.InputAdornmentField

Property 'InputAdornmentField' does not exist on type 'FieldApi<...>'.ts(2339)

This suggests that the custom field components defined in the form hook are not being registered or propagated through context.


My components are nested several levels deep, so I rely heavily on the context provider. I have followed the documentation and this is my index.ts setup:

"use client";

import { createFormHook, createFormHookContexts } from "@tanstack/react-form";

import AsyncComboboxField from "./async-combobox-field";
import CheckboxField from "./checkbox-field";
import InputAdornmentField from "./input-adornment-field";
import SelectField from "./select-field";
import TextAreaField from "./text-area-field";

export const { fieldContext, formContext, useFieldContext, useFormContext } =
  createFormHookContexts();

export const { useAppForm } = createFormHook({
  fieldComponents: {
    AsyncComboboxField,
    CheckboxField,
    InputAdornmentField,
    SelectField,
    TextAreaField,
  },
  fieldContext,
  formComponents: {},
  formContext,
});

At this point I am not sure whether:

  • I am missing a required wrapper or provider,
  • <form.AppForm> is not intended to behave like the documentation implies, or
  • there is an issue with how types are inferred when using createFormHook.

Any clarification, along with improvements to the documentation around context behaviour and type inference, would be greatly appreciated.

Expected behavior

  • <form.AppForm> should provide the full form context to all nested components, including type information and registered field components.
  • useFormContext() should return a correctly typed Field component and full form state within any child component.
  • Field names such as "apiKey" should be validated against the form’s data shape rather than resolving to never.
  • Custom field components (e.g. InputAdornmentField) should be accessible via field.InputAdornmentField when registered in createFormHook.
  • Type inference should correctly propagate from the form initialisation to every descendant without needing to manually pass the form object.

How often does this bug happen?

None

Screenshots or Videos

No response

Platform

  • Windows 11

TanStack Form adapter

None

TanStack Form version

1.27.1

TypeScript version

5.9.3

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions