{"record":{"id":"56580ff643b1d020","repo":"gleam-lang/gleam","slug":"hydrator-must-not-store-non-generic-types-here","errorCode":null,"errorMessage":"Hydrator must not store non generic types here","messagePattern":"Hydrator must not store non generic types here","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler-core/src/type_.rs","lineNumber":1108,"sourceCode":"impl TypeVariantConstructors {\n    pub(crate) fn new(\n        variants: Vec<TypeValueConstructor>,\n        type_parameters: &[&EcoString],\n        opaque: Opaque,\n        hydrator: Hydrator,\n    ) -> TypeVariantConstructors {\n        let named_types = hydrator.named_type_variables();\n        let type_parameters = type_parameters\n            .iter()\n            .map(|&p| {\n                let t = named_types\n                    .get(p)\n                    .expect(\"Type parameter not found in hydrator\");\n                let error = \"Hydrator must not store non generic types here\";\n                match t.type_.as_ref() {\n                    Type::Var { type_ } => match type_.borrow().deref() {\n                        TypeVar::Generic { id } => *id,\n                        TypeVar::Unbound { .. } | TypeVar::Link { .. } => panic!(\"{}\", error),\n                    },\n                    Type::Named { .. } | Type::Fn { .. } | Type::Tuple { .. } => {\n                        panic!(\"{}\", error)\n                    }\n                }\n            })\n            .collect_vec();\n        Self {\n            type_parameters_ids: type_parameters,\n            variants,\n            opaque,\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]\npub struct TypeValueConstructor {\n    pub name: EcoString,","sourceCodeStart":1090,"sourceCodeEnd":1126,"githubUrl":"https://github.com/gleam-lang/gleam/blob/15b07c783065c92bb016b1b74ed0995a5259850f/compiler-core/src/type_.rs#L1090-L1126","documentation":"An internal invariant panic in the Gleam type hydrator (`type_.rs:1108`). While collecting generic type parameters, the hydrator expects every stored type entry to be a `Type::Var` wrapping a `TypeVar::Generic`. If it finds an `Unbound`/`Link` type variable, or a concrete `Named`/`Fn`/`Tuple` type, it panics because the hydrator was populated with non-generic types — meaning an earlier type-annotation phase failed to register only generic parameters.","triggerScenarios":"During hydrator construction from a type annotation, a stored parameter resolves to a non-generic type: an unbound or linked type variable, or a fully concrete Named/Fn/Tuple type, is present in the hydrator's type map when generic parameter IDs are collected.","commonSituations":"A compiler bug in annotation parsing/instantiation; a malformed or exotic type annotation that confuses the hydrator (e.g. a value-type used where a generic parameter is expected); encountering it while hacking on the compiler itself or after a version upgrade changes inference behaviour.","solutions":["This is a compiler-internal invariant: report it as a bug to the Gleam repository with the exact source snippet and compiler version that triggered it.","Check the type annotation at the reported location for misuse of concrete types where type parameters are expected, and simplify the annotation.","If you are modifying the compiler, fix the code path that inserts non-generic types into the hydrator (only generic `TypeVar`s should be stored).","Try upgrading or downgrading the Gleam version — this may be a known regression fixed in a later release."],"exampleFix":"// before (registering a parameter without checking it is generic)\nhydrator.store_type(name, concrete_type);\n\n// after\nif let Type::Var { type_ } = concrete_type.as_ref() {\n    if matches!(type_.borrow().deref(), TypeVar::Generic { .. }) {\n        hydrator.store_type(name, concrete_type);\n    }\n}","handlingStrategy":"validation","validationCode":"// Rust: validate before storing into the hydrator\nfn is_generic_var(t: &Type) -> bool {\n    matches!(\n        t,\n        Type::Var { type_ }\n            if matches!(&*type_.borrow(), TypeVar::Generic { .. })\n    )\n}","typeGuard":"fn is_generic_var(t: &Type) -> bool {\n    matches!(t, Type::Var { type_ } if matches!(&*type_.borrow(), TypeVar::Generic { .. }))\n}","tryCatchPattern":"// Panics are not catchable in Rust; the guard is to validate before insertion\nassert!(\n    is_generic_var(&param_type),\n    \"hydrator parameters must be generic vars, got {:?}\",\n    param_type\n);","preventionTips":["Only insert types into the hydrator after verifying they are generic variables.","When adding new annotation forms, add unit tests covering hydrator registration.","Report any user-facing reproduction to the Gleam maintainers — this panic indicates a compiler bug."],"tags":["type-system","internal-invariant","compiler-bug","panic"],"backgroundTag":"internal-invariant-violation","analyzedSha":"15b07c783065c92bb016b1b74ed0995a5259850f","analyzedAt":"2026-09-14T11:14:59.388Z","contentChangedAt":"2026-09-14T11:14:59.388Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}