Again sorry for the Claude written issue, but this came out of the automate update, will try and validate this and find more details later on when I have time. Sorry figured it was better to report this now, than hold it back until I can fully understand it. Feel free to close if needed.
Flow version: 0.321.0 (regression from 0.318.0, which checked the same code with no errors)
Summary
The Rust-backed checker panics (internal compiler error, brings the server down with exit 78) instead of emitting a type error when checking react-hook-form's DeepRequired<T> type. The crash fires whenever a file instantiates an RHF form whose value type contains primitive fields.
The proximate cause is the recursive homomorphic mapped type bottoming out on a primitive: DeepRequired<T[K]> is evaluated where T[K] is string/boolean/etc., and the object-kit path panics rather than producing a graceful error. A simplified standalone version of the same shape yields a clean not-an-object error instead of crashing, so the panic appears specific to the full DeepRequired + FieldErrorsImpl<DeepRequired<T>> + template-literal-key combination in the real libdef — I was not able to reduce it to a minimal standalone snippet.
Triggering type (from the react-hook-form libdef)
declare export type DeepRequired<T> = T extends
| BrowserNativeObject
| Blob
? T
: { [K in keyof T]-?: NonNullable<DeepRequired<T[K]>> };
// ... used downstream as:
declare export type FieldErrors<T: FieldValues = FieldValues> = Partial<
FieldValues extends IsAny<FieldValues>
? any
: FieldErrorsImpl<DeepRequired<T>>,
> & { root?: ({ [key: string]: GlobalError } & GlobalError) };
Checking any module that instantiates FieldErrors<SomeForm> (i.e. uses useForm<SomeForm>()) where SomeForm has primitive fields triggers the panic.
Expected behavior
Either accept the type or emit a normal type error — never panic. (0.318.0 / OCaml checks the entire codebase using this libdef with No errors!.)
Actual behavior (0.321.0)
The server crashes on startup / full check:
thread '<unnamed>' panicked at crates/flow_typing_flow_common/src/flow_js_utils.rs:1297:21:
Non speculating: Speculative(SpeculativeError(EInvalidObjectKit(EInvalidObjectKitData {
reason: VirtualReasonInner { desc: RString,
loc: ... LibFile("react-hook-form_v7.x.x.js") line: 255 ..., // the `{ [K in keyof T]-?: ... }` mapped type in DeepRequired
def_loc_opt: Some(... SourceFile("<a form component>") ...) }, // the concrete form field
reason_op: VirtualReasonInner { desc: RObjectType, loc: ... line 255 ... },
use_op: Op(TypeApplication {
type_: ... RTypeApp(RType(Name("DeepRequired"))) ... line 276 ... // FieldErrorsImpl<DeepRequired<T>>
})
})))
Unhandled exception: Non speculating: Speculative(SpeculativeError(EInvalidObjectKit(...)))
Could not start Flow server! (exit code 78)
desc varies with the offending field type (RString, RBoolean, …), confirming the trigger is the recursion reaching a primitive.
Workaround
Bottoming out the recursion on non-object types stops the panic:
declare export type DeepRequired<T> = T extends
| BrowserNativeObject
| Blob
? T
: T extends { ... }
? { [K in keyof T]-?: NonNullable<DeepRequired<T[K]>> }
: T;
Again sorry for the Claude written issue, but this came out of the automate update, will try and validate this and find more details later on when I have time. Sorry figured it was better to report this now, than hold it back until I can fully understand it. Feel free to close if needed.
Flow version: 0.321.0 (regression from 0.318.0, which checked the same code with no errors)
Summary
The Rust-backed checker panics (internal compiler error, brings the server down with exit 78) instead of emitting a type error when checking
react-hook-form'sDeepRequired<T>type. The crash fires whenever a file instantiates an RHF form whose value type contains primitive fields.The proximate cause is the recursive homomorphic mapped type bottoming out on a primitive:
DeepRequired<T[K]>is evaluated whereT[K]isstring/boolean/etc., and the object-kit path panics rather than producing a graceful error. A simplified standalone version of the same shape yields a cleannot-an-objecterror instead of crashing, so the panic appears specific to the fullDeepRequired+FieldErrorsImpl<DeepRequired<T>>+ template-literal-key combination in the real libdef — I was not able to reduce it to a minimal standalone snippet.Triggering type (from the
react-hook-formlibdef)Checking any module that instantiates
FieldErrors<SomeForm>(i.e. usesuseForm<SomeForm>()) whereSomeFormhas primitive fields triggers the panic.Expected behavior
Either accept the type or emit a normal type error — never panic. (0.318.0 / OCaml checks the entire codebase using this libdef with
No errors!.)Actual behavior (0.321.0)
The server crashes on startup / full check:
descvaries with the offending field type (RString,RBoolean, …), confirming the trigger is the recursion reaching a primitive.Workaround
Bottoming out the recursion on non-object types stops the panic: