{"record":{"id":"7d7b91d4acd7e0ba","repo":"flowable/flowable-engine","slug":"the-attribute-must-resolve-to-an-number-or-a-s","errorCode":null,"errorMessage":"The [<attribute>] must resolve to an Number or a String that can be parsed as an Integer. Resolved to [<class>] for [<value>]","messagePattern":"The \\[<attribute>\\] must resolve to an Number or a String that can be parsed as an Integer\\. Resolved to \\[<class>\\] for \\[<value>\\]","errorType":"validation","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"modules/flowable-event-registry-spring/src/main/java/org/flowable/eventregistry/spring/kafka/KafkaChannelDefinitionProcessor.java","lineNumber":462,"sourceCode":"\n            channelModel.setOutboundEventChannelAdapter(new KafkaOperationsOutboundEventChannelAdapter(\n                            kafkaOperations, partitionProvider, resolvedTopic, messageKeyProvider));\n        }\n    }\n\n    protected Integer resolveExpressionAsInteger(String value, String attribute) {\n        return resolveExpressionAsInteger(value, attribute, null);\n    }\n\n    protected Integer resolveExpressionAsInteger(String value, String attribute, Integer defaultValue) {\n        Object resolved = resolveExpression(value);\n        Integer result = defaultValue;\n        if (resolved instanceof String) {\n            result = Integer.parseInt((String) resolved);\n        } else if (resolved instanceof Number) {\n            result = ((Number) resolved).intValue();\n        } else if (resolved != null) {\n            throw new IllegalStateException(\n                \"The [\" + attribute + \"] must resolve to an Number or a String that can be parsed as an Integer. \"\n                    + \"Resolved to [\" + resolved.getClass() + \"] for [\" + value + \"]\");\n        }\n        return result;\n    }\n\n    protected Long resolveExpressionAsLong(String value, String attribute) {\n        Object resolved = resolveExpression(value);\n        Long result = null;\n        if (resolved instanceof String) {\n            result = Long.parseLong((String) resolved);\n        } else if (resolved instanceof Number) {\n            result = ((Number) resolved).longValue();\n        } else if (resolved != null) {\n            throw new IllegalStateException(\n                    \"The [\" + attribute + \"] must resolve to an Number or a String that can be parsed as a Long. \"\n                            + \"Resolved to [\" + resolved.getClass() + \"] for [\" + value + \"]\");\n        }","sourceCodeStart":444,"sourceCodeEnd":480,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-event-registry-spring/src/main/java/org/flowable/eventregistry/spring/kafka/KafkaChannelDefinitionProcessor.java#L444-L480","documentation":"resolveExpressionAsInteger resolves a channel-model attribute expression (e.g. a SpEL/placeholder) and expects null, a Number, or a String parseable as Integer. If the resolved value is any other type (e.g. Boolean, Map, bean), IllegalStateException is thrown naming the attribute, resolved class, and raw value.","triggerScenarios":"An integer attribute of the Kafka channel model (e.g. a retry-config field like maxAttempts or concurrency) is set via an expression that resolves to a non-numeric object, and resolveExpressionAsInteger (directly or via resolveRetryConfiguration) processes it.","commonSituations":"Placeholder points to a bean/Map instead of a property; YAML property typed as list/boolean; expression typo resolving a method result of wrong type; property missing type coercion in a custom resolver.","solutions":["Point the attribute expression at a numeric value or numeric String (e.g. ${kafka.retry.maxAttempts} resolving to \"3\").","Check the resolved bean/property type; change it to Integer/int in the configuration class.","Use Integer.parseInt-safe values: ensure no units like \"3s\" or thousands separators in the String.","Cast or convert the expression, e.g. ${...} backed by a conversion service that yields Number."],"exampleFix":"// before (application.yml)\nkafka:\n  retry:\n    maxAttempts: three   # resolves as non-numeric string? or a map\n\n// after\nkafka:\n  retry:\n    maxAttempts: 3","handlingStrategy":"type-guard","validationCode":"Object v = resolveExpression(value);\nif (v != null && !(v instanceof Number) && !(v instanceof String)) throw new IllegalArgumentException(attribute + \" must be numeric\");","typeGuard":"boolean isIntegerLike(Object v) { return v == null || v instanceof Number || (v instanceof String s && s.matches(\"-?\\\\d+\")); }","tryCatchPattern":"try { processor.createEndpointConfigurations(...); } catch (IllegalStateException e) { if (e.getMessage().contains(\"must resolve to\")) { log.error(\"Bad attribute type: {}\", e.getMessage()); } else throw e; }","preventionTips":["Quote numeric literals in channel model YAML/JSON","Keep retry/attempt attributes as ints in backing config classes","Test placeholder resolution in a boot-time validation test"],"tags":["kafka","type-mismatch","expression-resolution","spring"],"backgroundTag":"type-mismatch","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}