{"record":{"id":"ec4b1f52913bafcb","repo":"quarkusio/quarkus","slug":"knative-events-function-mapping-does-not-map-to-a","errorCode":null,"errorMessage":"knative-events.function-mapping does not map to a function: ${functionName}","messagePattern":"knative-events\\.function-mapping does not map to a function: (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"extensions/funqy/funqy-knative-events/runtime/src/main/java/io/quarkus/funqy/runtime/bindings/knative/events/KnativeEventsBindingRecorder.java","lineNumber":222,"sourceCode":"        // This needs to happen in start at RUNTIME so that\n        // mappings can be overridden by environment variables\n        FunctionInvoker defaultInvoker = null;\n        if (runtimeConfig.getValue().export().isPresent()) {\n            defaultInvoker = FunctionRecorder.registry.matchInvoker(runtimeConfig.getValue().export().get());\n            if (defaultInvoker == null) {\n                throw new RuntimeException(\n                        \"quarkus.funqy.export value does not map a function: \" + runtimeConfig.getValue().export().get());\n            }\n\n        }\n\n        if (eventsRuntimeConfig.getValue().mapping() != null) {\n            for (Map.Entry<String, FunqyKnativeEventsConfig.FunctionMapping> entry : eventsRuntimeConfig.getValue().mapping()\n                    .entrySet()) {\n                String functionName = entry.getKey();\n                FunctionInvoker invoker = FunctionRecorder.registry.matchInvoker(functionName);\n                if (invoker == null) {\n                    throw new RuntimeException(\"knative-events.function-mapping does not map to a function: \" + functionName);\n                }\n                FunqyKnativeEventsConfig.FunctionMapping mapping = entry.getValue();\n                if (mapping.trigger().isPresent()) {\n                    typeTriggers.compute(mapping.trigger().get(), (k, v) -> {\n                        if (v == null) {\n                            v = new ArrayList<>();\n                        }\n                        v.add(invoker);\n                        return v;\n                    });\n                }\n                if (invoker.hasOutput()) {\n                    if (mapping.responseSource().isPresent()) {\n                        invoker.getBindingContext().put(RESPONSE_SOURCE, mapping.responseSource().get());\n                    }\n                    if (mapping.responseType().isPresent()) {\n                        invoker.getBindingContext().put(RESPONSE_TYPE, mapping.responseType().get());\n                    }","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/funqy/funqy-knative-events/runtime/src/main/java/io/quarkus/funqy/runtime/bindings/knative/events/KnativeEventsBindingRecorder.java#L204-L240","documentation":"At startup, the Funqy Knative Events binding recorder validates every entry in quarkus.funqy.knative-events.function-mapping against the registry of @Funq functions built at build time. If a mapping key does not name a registered function, FunctionRecorder.registry.matchInvoker() returns null and a RuntimeException is thrown. This fails the application start so a broken mapping is caught immediately rather than at first request.","triggerScenarios":"A quarkus.funqy.knative-events.function-mapping.\"<name>\".trigger-type (or similar) config property references a function name that has no corresponding @Funq-annotated method or has been renamed/removed.","commonSituations":"Renaming a @Funq method (or the function's exported name) without updating the mapping property; copy-pasting mapping config from another project; typo in the function name; removing a function but leaving stale config in application.properties or an env var override (quarkus.funqy.knative-events.function-mapping env keys).","solutions":["Open application.properties and check every key under quarkus.funqy.knative-events.function-mapping; each key must exactly match a registered Funqy function name","Set the function's name explicitly with @Funq(\"name\") if the method name differs from the mapping key","Remove or correct stale mapping entries left from deleted or renamed functions","Enable Funqy logging or inspect the build-time function registry to list valid function names"],"exampleFix":"// before (application.properties)\nquarkus.funqy.knative-events.function-mapping.\"processOrder\".trigger-type=my.trigger\n// after (function renamed to handleOrder)\nquarkus.funqy.knative-events.function-mapping.\"handleOrder\".trigger-type=my.trigger","handlingStrategy":"validation","validationCode":"// Before startup, verify mapping keys exist in the function registry\nSet<String> registered = FunctionRecorder.registry != null\n    ? FunctionRecorder.registry.matchInvokerNames() : Set.of();\neventsRuntimeConfig.getValue().mapping().keySet().stream()\n    .filter(k -> !registered.contains(k))\n    .forEach(k -> log.warnf(\"Unknown knative-events function-mapping key: %s\", k));","typeGuard":null,"tryCatchPattern":"try {\n    binder.start();\n} catch (RuntimeException e) {\n    if (e.getMessage().contains(\"function-mapping does not map to a function\")) {\n        log.error(\"Fix quarkus.funqy.knative-events.function-mapping keys to match registered @Funq functions\");\n    }\n    throw e;\n}","preventionTips":["Keep mapping keys in one application.properties section with a comment listing valid function names","Use @Funq(\"explicit-name\") to decouple function names from Java method names","Add a startup health check that asserts every mapping key matches a registered function","Review mapping config in code review whenever @Funq methods are renamed"],"tags":["quarkus","funqy","knative","config"],"backgroundTag":"function-mapping-not-found","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}