{"record":{"id":"3223511df1a7230d","repo":"slint-ui/slint","slug":"expression-objectaccess-cannot-find-a-key-in-an-object","errorCode":null,"errorMessage":"Expression::ObjectAccess: Cannot find a key in an object","messagePattern":"Expression::ObjectAccess: Cannot find a key in an object","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/compiler/generator/cpp.rs","lineNumber":4955,"sourceCode":"        }\n        Expression::Closure { arg_name, expression } => {\n            let arg = ident(arg_name);\n            let expr = compile_expression(expression, ctx);\n\n            format!(\"[&](auto const &{arg}) -> bool {{ return {expr}; }}\")\n        }\n        // Generated code has no debug hooks; use the wrapped expression.\n        Expression::DebugHook { expression, .. } => compile_expression(expression, ctx),\n    }\n}\n\nfn struct_field_access(base: String, s: &crate::langtype::Struct, name: &str) -> String {\n    if s.name.is_none() {\n        let index = s\n            .fields\n            .keys()\n            .position(|k| k == name)\n            .expect(\"Expression::ObjectAccess: Cannot find a key in an object\");\n        format!(\"std::get<{}>({})\", index, base)\n    } else {\n        format!(\"{}.{}\", base, ident(name))\n    }\n}\n\nfn compile_builtin_function_call(\n    function: BuiltinFunction,\n    arguments: &[llr::Expression],\n    ctx: &EvaluationContext,\n) -> String {\n    let mut a = arguments.iter().map(|a| compile_expression(a, ctx));\n    let pi_180 = std::f64::consts::PI / 180.0;\n\n    match function {\n        BuiltinFunction::GetWindowScaleFactor => {\n            format!(\"{}.scale_factor()\", access_window_field(ctx))\n        }","sourceCodeStart":4937,"sourceCodeEnd":4973,"githubUrl":"https://github.com/slint-ui/slint/blob/3a7e700487dc74d404cad0726378053ab763d4e0/internal/compiler/generator/cpp.rs#L4937-L4973","documentation":"When generating C++ for `Expression::ObjectAccess`, anonymous structs are compiled to `std::tuple` and field access uses the field's positional index. `struct_field_access` panics if the requested key does not exist in the struct's field list, meaning the type checker let an access to a non-existent key slip through to code generation.","triggerScenarios":"ObjectAccess on an anonymous struct where `name` is not among `s.fields.keys()` — normally prevented by type checking; reaching it indicates a mismatch between the checked type and the generated struct, or a pass that rewrote struct fields without updating accesses.","commonSituations":"Compiler development: a normalization pass drops or renames struct fields; lookup/type-inference changes that produce an inconsistent Struct for object literals; regression tests with malformed expressions bypassing typecheck.","solutions":["Fix the upstream pass so the Struct type matches the actual fields of the object literal","Verify the type checker rejects unknown-key accesses before codegen and emits a proper diagnostic","Re-run the type-checking pass on the failing input to confirm the struct's fields"],"exampleFix":"// before\nlet index = s.fields.keys().position(|k| k == name).expect(\"...\");\n// after\nlet index = s.fields.keys().position(|k| k == name).unwrap_or_else(||\n    panic!(\"ObjectAccess: key '{name}' not in struct with fields {:?}\", s.fields.keys().collect::<Vec<_>>()));","handlingStrategy":"type-guard","validationCode":"fn struct_has_field(s: &Struct, name: &str) -> bool {\n    s.fields.keys().any(|k| k == name)\n}","typeGuard":"fn checked_field_index(s: &Struct, name: &str) -> Option<usize> {\n    s.fields.keys().position(|k| k == name)\n}","tryCatchPattern":null,"preventionTips":["Ensure the type checker validates every ObjectAccess key before codegen","Run type checking as a hard prerequisite of code generation in tests","Add regression tests for passes that rewrite anonymous struct fields","Log the struct's field list in the panic message for diagnosability"],"tags":["compiler","cpp-codegen","structs","internal-invariant"],"backgroundTag":"internal-invariant-violation","analyzedSha":"3a7e700487dc74d404cad0726378053ab763d4e0","analyzedAt":"2026-09-16T01:37:20.251Z","contentChangedAt":"2026-09-16T01:37:20.251Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}