{"record":{"id":"9a3430e74fec58a3","repo":"t8y2/dbx","slug":"no-writable-queue-for-topic-s","errorCode":null,"errorMessage":"no writable queue for topic %s","messagePattern":"no writable queue for topic (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agents/drivers/rocketmq/messages.go","lineNumber":348,"sourceCode":"\nfunc (a *rocketMQAgent) sendMessage(params map[string]any) (any, error) {\n\ttopic, err := requireString(params, \"topic\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tpayload, err := decodePayload(params)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tclient, config, _ := a.requireClient()\n\tctx, cancel := context.WithTimeout(context.Background(), config.RequestTimeout)\n\tdefer cancel()\n\ttargets, err := a.messageQueueTargets(ctx, client, topic, true)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif len(targets) == 0 {\n\t\treturn nil, fmt.Errorf(\"no writable queue for topic %s\", topic)\n\t}\n\tpartition, hasPartition := optionalInt(params, \"partition\")\n\tselected := targets[0]\n\tif hasPartition {\n\t\tfound := false\n\t\tfor _, target := range targets {\n\t\t\tif target.QueueID == partition {\n\t\t\t\tselected = target\n\t\t\t\tfound = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif !found {\n\t\t\treturn nil, fmt.Errorf(\"partition %d not found for topic %s\", partition, topic)\n\t\t}\n\t}\n\tcommand := buildSendMessageCommand(topic, payload, selected.QueueID, params, time.Now().UnixMilli())\n\tresponse, err := invokeRemotingAllowCodes(ctx, selected.Address, config.ConnectTimeout, command, 0, 10, 11, 12)","sourceCodeStart":330,"sourceCodeEnd":366,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/rocketmq/messages.go#L330-L366","documentation":"sendMessage calls messageQueueTargets with writable=true, which intersects the route's QueueDatas (WriteQueueNums, WRITE perm) with each broker's master address. If no queue can be assembled, there is nowhere to send the message and this error is returned.","triggerScenarios":"Calling sendMessage via dispatch for a topic whose route has zero writable queues: writeQueueNums 0 on all QueueDatas, WRITE perm bit cleared, no master address for any listed broker, or QueueDatas with no matching BrokerDatas.","commonSituations":"Topic set read-only during maintenance (perm=4); writeQueueNums shrunk to 0; master broker down so no '0' address; typo in topic name resolving to a non-writable route; incomplete auto-created topic route.","solutions":["Check mqadmin topicRoute <topic>; restore write queues with mqadmin updateTopic -r 8 -w 8 -t <topic>.","Verify the topic perm includes the WRITE bit (2; typical writable value 6).","Ensure a master broker (brokerId=0) for the topic is running and registered (mqadmin clusterList).","Confirm the topic name is correct and exists (mqadmin topicList).","Create the topic explicitly with mqadmin updateTopic instead of relying on autoCreateTopicEnable."],"exampleFix":"// before: read-only topic\nmqadmin updateTopic -n namesrv:9876 -t myTopic -r 8 -w 0 -p 4\n// after: restore write queues and permission\nmqadmin updateTopic -n namesrv:9876 -t myTopic -r 8 -w 8 -p 6","handlingStrategy":"validation","validationCode":"// Before sending, confirm the topic has writable queues.\nroute, err := client.ExamineTopicRouteInfo(ctx, topic)\nif err != nil { return err }\nmasters := map[string]bool{}\nfor _, bd := range route.BrokerDatas {\n    if a := bd.BrokerAddrs[\"0\"]; a != \"\" { masters[bd.BrokerName] = true }\n}\nwritable := 0\nfor _, qd := range route.QueueDatas {\n    if masters[qd.BrokerName] && qd.Perm&2 != 0 { writable += qd.WriteQueueNums }\n}\nif writable == 0 {\n    return fmt.Errorf(\"topic %s is not writable; check writeQueueNums/perm\", topic)\n}","typeGuard":"func topicWritable(route *admin.TopicRoute) bool {\n    masters := map[string]bool{}\n    for _, bd := range route.BrokerDatas {\n        if a := bd.BrokerAddrs[\"0\"]; a != \"\" { masters[bd.BrokerName] = true }\n    }\n    for _, qd := range route.QueueDatas {\n        if masters[qd.BrokerName] && qd.Perm&2 != 0 && qd.WriteQueueNums > 0 {\n            return true\n        }\n    }\n    return false\n}","tryCatchPattern":null,"preventionTips":["Create topics explicitly with mqadmin updateTopic and matching read/write queue counts (e.g. -r 8 -w 8).","Never set perm to read-only (4) while producers are active.","Monitor master broker liveness so you know when sends can't be routed.","Validate topic names against mqadmin topicList before dispatching sends."],"tags":["rocketmq","producer","topic","routing"],"backgroundTag":"no-writable-queue","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"}