{"record":{"id":"bdb5c11c93730d69","repo":"conductor-oss/conductor","slug":"exchange-type-is-undefined","errorCode":null,"errorMessage":"Exchange type is undefined","messagePattern":"Exchange type is undefined","errorType":"validation","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"amqp/src/main/java/com/netflix/conductor/contribs/queue/amqp/AMQPObservableQueue.java","lineNumber":561,"sourceCode":"                settings.getExchangeType(),\n                settings.isDurable(),\n                settings.autoDelete(),\n                settings.getArguments());\n    }\n\n    private AMQP.Exchange.DeclareOk getOrCreateExchange(\n            ConnectionType connectionType,\n            String name,\n            final String type,\n            final boolean isDurable,\n            final boolean autoDelete,\n            final Map<String, Object> arguments)\n            throws Exception {\n        if (StringUtils.isEmpty(name)) {\n            throw new RuntimeException(\"Exchange name is undefined\");\n        }\n        if (StringUtils.isEmpty(type)) {\n            throw new RuntimeException(\"Exchange type is undefined\");\n        }\n        Channel chn = null;\n        try {\n            LOGGER.debug(\"Creating exchange {} of type {}\", name, type);\n            chn =\n                    amqpConnection.getOrCreateChannel(\n                            connectionType, getSettings().getQueueOrExchangeName());\n            return chn.exchangeDeclare(name, type, isDurable, autoDelete, arguments);\n        } catch (final Exception e) {\n            LOGGER.warn(\"Failed to create exchange {} of type {}\", name, type, e);\n            throw e;\n        } finally {\n            if (chn != null) {\n                try {\n                    amqpConnection.returnChannel(connectionType, chn);\n                } catch (Exception e) {\n                    LOGGER.error(\"Failed to return the channel of {}. {}\", connectionType, e);\n                }","sourceCodeStart":543,"sourceCodeEnd":579,"githubUrl":"https://github.com/conductor-oss/conductor/blob/cf7c3e4a8adfb158be778ab1ec525323c363cd3a/amqp/src/main/java/com/netflix/conductor/contribs/queue/amqp/AMQPObservableQueue.java#L543-L579","documentation":"Thrown as RuntimeException by getOrCreateExchange when the 'type' argument (the AMQP exchange type: direct/fanout/topic/headers) is empty. The value comes from settings.getExchangeType(). RabbitMQ requires an exchange type at declare time, so an empty value cannot proceed.","triggerScenarios":"An exchange-typed AMQP URI with no exchangeType query parameter and no default exchangeType configured in AMQPEventQueueProperties. getOrCreateExchange(connectionType) passes settings.getExchangeType() which resolves to empty.","commonSituations":"Forgetting the exchangeType= query param in the URI when the global default is unset; setting conductor.workflow.event-queues.amqp.exchangeType to blank; upgrading config where the property key changed.","solutions":["Add exchangeType=topic (or direct/fanout/headers) to the amqp_exchange URI.","Set a non-empty default conductor.workflow.event-queues.amqp.exchangeType if exchanges are used broadly.","Validate the resolved settings.getExchangeType() before calling getOrCreateExchange."],"exampleFix":"// before\namqp_exchange:myExchange?durable=true\n// after\namqp_exchange:myExchange?exchangeType=topic&durable=true","handlingStrategy":"validation","validationCode":"import org.apache.commons.lang3.StringUtils;\nimport java.util.Set;\nString exchangeType = settings.getExchangeType();\nSet<String> valid = Set.of(\"direct\", \"fanout\", \"topic\", \"headers\");\nif (useExchange && (StringUtils.isBlank(exchangeType) || !valid.contains(exchangeType.toLowerCase()))) {\n    throw new IllegalStateException(\n        \"AMQP exchangeType must be one of \" + valid + \"; got: \" + exchangeType);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always include exchangeType= in exchange URIs or set a non-empty default property.","Validate the exchange type against the four legal AMQP values at startup.","Document the required param next to every amqp_exchange example."],"tags":["amqp","configuration","validation","queue"],"backgroundTag":null,"analyzedSha":"cf7c3e4a8adfb158be778ab1ec525323c363cd3a","analyzedAt":"2026-08-14T03:33:19.897Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}