{"record":{"id":"3eb5fc1c8ff5d3c0","repo":"t8y2/dbx","slug":"destinationtype-must-be-queue-or-exchange-got","errorCode":null,"errorMessage":"destinationType must be 'queue' or 'exchange', got '%s'","messagePattern":"destinationType must be 'queue' or 'exchange', got '(.+?)'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agents/drivers/rabbitmq/operations.go","lineNumber":577,"sourceCode":"func (s *server) unbind(params jsonObject) (any, error) {\n\tif err := s.applyBinding(params, false); err != nil {\n\t\treturn nil, err\n\t}\n\treturn okResult(), nil\n}\n\nfunc (s *server) applyBinding(params jsonObject, bind bool) error {\n\tsource, err := requireBindingName(params, \"source\")\n\tif err != nil {\n\t\treturn err\n\t}\n\tdestination, err := requireBindingName(params, \"destination\")\n\tif err != nil {\n\t\treturn err\n\t}\n\tdestinationType := stringOrDefault(params, \"destinationType\", stringOrEmpty(params, \"destination_type\"))\n\tif destinationType != \"queue\" && destinationType != \"exchange\" {\n\t\treturn fmt.Errorf(\"destinationType must be 'queue' or 'exchange', got '%s'\", destinationType)\n\t}\n\troutingKey := stringOrDefault(params, \"routingKey\", stringOrEmpty(params, \"routing_key\"))\n\targuments := bindingArguments(params)\n\tchannel, err := s.channelFor(params)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif destinationType == \"queue\" {\n\t\tif bind {\n\t\t\treturn channel.QueueBind(destination, routingKey, source, false, arguments)\n\t\t}\n\t\treturn channel.QueueUnbind(destination, routingKey, source, arguments)\n\t}\n\tif bind {\n\t\treturn channel.ExchangeBind(destination, routingKey, source, false, arguments)\n\t}\n\treturn channel.ExchangeUnbind(destination, routingKey, source, false, arguments)\n}","sourceCodeStart":559,"sourceCodeEnd":595,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/rabbitmq/operations.go#L559-L595","documentation":"applyBinding (used by both bind and unbind) requires destinationType (or destination_type) to be exactly 'queue' or 'exchange'. Any other value — including empty string or snake_case variants like 'que' — is rejected before touching the channel.","triggerScenarios":"Calling bind/unbind with destinationType omitted (falls back to '' since destination_type is also missing), or set to misspelled/uppercase values like 'Queue', 'echange', 'topic'.","commonSituations":"Parameter name mismatches between caller and driver (destinationType vs destination_type), uppercase enum from another system, forgetting to pass the field entirely.","solutions":["Set destinationType to exactly 'queue' or 'exchange' (lowercase)","Check you are passing the right parameter name (destinationType or destination_type) and it is not being dropped by your serialization","Normalize/validate the value in your calling code before dispatching"],"exampleFix":"// before\nawait client.bind({\"source\": \"events\", \"destination\": \"orders\", \"destinationType\": \"Queue\", \"routingKey\": \"o.#\"})\n// after\nawait client.bind({\"source\": \"events\", \"destination\": \"orders\", \"destinationType\": \"queue\", \"routingKey\": \"o.#\"})","handlingStrategy":"validation","validationCode":"function validateDestinationType(t) {\n  if (t !== \"queue\" && t !== \"exchange\") {\n    throw new Error(`destinationType must be 'queue' or 'exchange'`)\n  }\n  return t\n}","typeGuard":"function isDestinationType(v) {\n  return v === \"queue\" || v === \"exchange\"\n}","tryCatchPattern":null,"preventionTips":["Always pass destinationType explicitly; never rely on the destination_type fallback","Normalize casing/trimming before dispatch","Unit-test bind/unbind builders to assert the enum value"],"tags":["rabbitmq","validation","binding","enum"],"backgroundTag":"invalid-enum-value","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}