{"record":{"id":"e784be48a8f3244b","repo":"flowable/flowable-engine","slug":"error-writing-channel-json","errorCode":null,"errorMessage":"Error writing channel json","messagePattern":"Error writing channel json","errorType":"exception","errorClass":"FlowableEventJsonException","httpStatus":null,"severity":"error","filePath":"modules/flowable-event-registry-json-converter/src/main/java/org/flowable/eventregistry/json/converter/ChannelJsonConverter.java","lineNumber":125,"sourceCode":"        Class<? extends ChannelModel> channelClass = channelModelClasses.get(channelType + \"-\" + type);\n        if (channelClass != null) {\n            return channelClass;\n        }\n\n        throw new FlowableEventJsonException(\"Not supported \" + channelType + \" channel model type was found \" + type);\n    }\n\n    protected void validateChannel(ChannelModel channelModel) {\n        for (ChannelValidator validator : validators) {\n            validator.validateChannel(channelModel);\n        }\n    }\n\n    public String convertToJson(ChannelModel definition) {\n        try {\n            return objectMapperSupplier.get().writeValueAsString(definition);\n        } catch (Exception e) {\n            throw new FlowableEventJsonException(\"Error writing channel json\", e);\n        }\n    }\n\n    public List<ChannelValidator> getValidators() {\n        return validators;\n    }\n\n    public void addValidator(ChannelValidator validator) {\n        validators.add(validator);\n    }\n\n    public void setValidators(List<ChannelValidator> validators) {\n        this.validators = validators;\n    }\n\n    public Map<String, Class<? extends ChannelModel>> getChannelModelClasses() {\n        return channelModelClasses;\n    }","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-event-registry-json-converter/src/main/java/org/flowable/eventregistry/json/converter/ChannelJsonConverter.java#L107-L143","documentation":"ChannelJsonConverter.convertToJson serializes a ChannelModel to its JSON representation. Any ObjectMapper serialization failure is wrapped as FlowableEventJsonException('Error writing channel json') with the cause attached. It indicates a channel model that cannot be converted to JSON.","triggerScenarios":"Calling convertToJson with a ChannelModel containing unserializable state, or the ObjectMapper supplier throwing (e.g. invalid serialization configuration, self-referencing or custom model class Jackson cannot handle).","commonSituations":"Using a custom ChannelModel subclass not designed for Jackson serialization, cyclic references in a custom model, or a broken ObjectMapper supplied via objectMapperSupplier.","solutions":["Inspect e.getCause() for the Jackson serialization error and fix the offending model field.","Make the custom ChannelModel subclass Jackson-friendly (plain getters, no cycles) or annotate it properly.","Verify the configured ObjectMapper is valid and initialized correctly."],"exampleFix":"// before\nString json = converter.convertToJson(customChannelModel); // throws on cyclic field\n// after\n@JsonIgnore\nprivate SomeCycleParent parent; // fix the model, then serialize\nString json = converter.convertToJson(customChannelModel);","handlingStrategy":"try-catch","validationCode":"if (channelModel == null || channelModel.getKey() == null) {\n    throw new IllegalArgumentException(\"ChannelModel and its key must be set before serializing\");\n}","typeGuard":"boolean isSerializable(ChannelModel m) {\n    return m != null && m.getKey() != null && !m.getKey().isEmpty();\n}","tryCatchPattern":"try {\n    String json = converter.convertToJson(channelModel);\n} catch (FlowableEventJsonException e) {\n    LOG.error(\"Failed to serialize channel model: {}\", e.getCause() != null ? e.getCause().getMessage() : e.getMessage());\n    throw e;\n}","preventionTips":["Keep custom ChannelModel subclasses Jackson-friendly (no cycles, plain getters).","Serialize once in tests to catch model issues before production.","Verify the ObjectMapper supplier returns a configured mapper."],"tags":["json","serialization","channel-model"],"backgroundTag":"json-marshal-failed","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"}