{"record":{"id":"8fac7f5d09deafdb","repo":"facebook/flow","slug":"records-cannot-have-getters","errorCode":null,"errorMessage":"Records cannot have getters","messagePattern":"Records cannot have getters","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"rust_port/crates/flow_typing_statement/src/statement.rs","lineNumber":18860,"sourceCode":"                                                }),\n                                            ),\n                                            value: (func_loc_c, typed_func),\n                                            kind: kind_c,\n                                            static_: static_c,\n                                            override_: false,\n                                            ts_accessibility: None,\n                                            decorators: vec![].into(),\n                                            comments: method_comments_c,\n                                        },\n                                    ))\n                                };\n\n                                match kind {\n                                    ast::class::MethodKind::Constructor => {\n                                        panic!(\"Records cannot have constructors\")\n                                    }\n                                    ast::class::MethodKind::Get => {\n                                        panic!(\"Records cannot have getters\")\n                                    }\n                                    ast::class::MethodKind::Set => {\n                                        panic!(\"Records cannot have setters\")\n                                    }\n                                    ast::class::MethodKind::Method => {\n                                        check_duplicate_name(\n                                            &mut public_seen_names,\n                                            method_id_loc.dupe(),\n                                            &Name::new(name.dupe()),\n                                            static_,\n                                            false,\n                                            ClassMemberKind::ClassMemberMethod,\n                                        );\n                                        class_sig::add_method(\n                                            static_,\n                                            false,\n                                            false,\n                                            Name::new(name),","sourceCodeStart":18842,"sourceCodeEnd":18878,"githubUrl":"https://github.com/facebook/flow/blob/5c865861998a8ccb7dbc82b0c1f511e9ef60c3d9/rust_port/crates/flow_typing_statement/src/statement.rs#L18842-L18878","documentation":"In Flow record declarations, the typing pass panics on MethodKind::Get: records have no accessor semantics, so a getter in a record body crashes the statement typer rather than producing a diagnostic. Like the constructor case, this is an intentional hard boundary — records only model data plus plain methods.","triggerScenarios":"Typechecking a record whose body contains a getter — record Config { get name(): string { ... } } — where the parser accepted the accessor and typing reaches the member lowering.","commonSituations":"Class-to-record conversions that keep accessors; developers assuming record getters behave like class getters; codemods and code generators emitting accessors into record bodies.","solutions":["Remove the getter from the record body.","Replace derived values with a plain function taking the record: function getName(c: Config): string.","Keep accessors by using a class instead of a record.","Add a lint rule that rejects accessor members inside record bodies."],"exampleFix":"// before\nrecord Config {\n  name_: string;\n  get name(): string { return this.name_; }\n}\n\n// after: compute via a function\nrecord Config { name: string; }\nfunction getName(c: Config): string { return c.name; }","handlingStrategy":"validation","validationCode":"// lint before typechecking: records must not contain getters\nfunction recordHasAccessor(node) {\n  return node.body.some(\n    (el) => el.type === 'Method' && (el.kind === 'get' || el.kind === 'set')\n  );\n}\nif (recordHasAccessor(recordNode)) reportError(recordNode, 'records cannot have accessors');","typeGuard":"function recordMemberAllowed(el) {\n  if (el.type === 'Property') return true;\n  if (el.type !== 'Method') return false;\n  return el.kind === 'method' && el.key.type === 'Identifier';\n}","tryCatchPattern":null,"preventionTips":["Teach refactoring tools that record is data-only: derived values become plain functions.","Add accessor-in-record to the lint config together with the constructor rule.","Review codemod output for accessor members before committing conversions.","Prefer classes when accessors carry real behavior."],"tags":["flow","records","syntax","typing","class-members","getter"],"backgroundTag":"flow-record-syntax-error","analyzedSha":"5c865861998a8ccb7dbc82b0c1f511e9ef60c3d9","analyzedAt":"2026-08-20T10:41:37.992Z","contentChangedAt":"2026-08-20T10:41:37.992Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}