ambiguous-pointer opened a new issue, #1529:
URL: https://github.com/apache/dubbo-admin/issues/1529

   # [Bug][ai] `ai/` 模块在 Go 1.26 下无法编译:传递依赖 `bytedance/sonic v1.14.1` 报 
`undefined: GoMapIterator`
   
   ## 概述(Summary)
   
   `ai/`(`dubbo-admin-ai`)模块在 **Go ≥ 1.26** 的宿主机上执行 `go build .` 会直接编译失败,导致 AI 
Agent 服务无法启动。报错来自一个**间接传递依赖** `github.com/bytedance/sonic 
v1.14.1`(项目源码中没有任何地方直接 import 或调用它),而该版本尚未适配 Go 1.26 的 map 内部实现变更。
   
   上游官方已于 **v1.15.0** 修复(PR bytedance/sonic#898),因此**只需把 sonic 升级到 v1.15.0 
即可解决**,无需修改业务代码。
   
   ---
   
   ## Environment
   
   - Deploy env: 本地/任意可运行 `go build` 的 Linux 宿主(复现与部署环境无关)
   - Dubbo application version: dubbo-admin 主仓库 + `ai/` 
子模块(`dubbo-admin-ai`,`ai/go.mod` 声明 `go 1.24.11`)
   - Go 工具链: `go1.26.4 linux/amd64`(`GOTOOLCHAIN=auto`)
   - 关键依赖版本:
     - `github.com/cloudwego/eino v0.7.34`
     - `github.com/bytedance/sonic v1.14.1`(indirect,问题版本)
     - `github.com/bytedance/sonic/loader v0.3.0`
     - `github.com/firebase/genkit/go v1.2.0`
   
   ---
   
   ## Issue description
   
   在 `ai/` 目录下执行构建(即使 .env 等运行期配置全部就绪),编译阶段即失败,服务无法启动。
   
   错误信息(与上游 issue 完全一致,行号精确到 `stubs.go:33:22` 与 `stubs.go:36:54`):
   
   ```text
   # github.com/bytedance/sonic/internal/rt
   
/opt/.tmp/.go-path/pkg/mod/github.com/bytedance/[email protected]/internal/rt/stubs.go:33:22:
 undefined: GoMapIterator
   
/opt/.tmp/.go-path/pkg/mod/github.com/bytedance/[email protected]/internal/rt/stubs.go:36:54:
 undefined: GoMapIterator
   ```
   
   ### Steps to reproduce
   
   ```bash
   cd ai
   go build .
   ```
   
   ### Expected behavior
   
   - 期望:`go build .` 编译通过,随后可正常启动 AI Agent 服务。
   
   ### Actual behavior
   
   - 实际:构建在编译 `bytedance/sonic/internal/rt` 时失败,`undefined: 
GoMapIterator`;无任何可执行产物生成。
   
   ---
   
   ## Root cause analysis(根因分析)
   
   ### 1. 依赖链:sonic 是被"真实使用"的传递依赖
   
   项目源码**没有直接 import** `bytedance/sonic`(`rg -n 'bytedance/sonic' --glob 
'*.go'` 无结果),但它在构建图中:
   
   ```text
   dubbo-admin-ai/component/rag
     → github.com/cloudwego/eino/schema
     → github.com/bytedance/sonic
   ```
   
   - `component/rag/rag.go:33` import 
`github.com/cloudwego/eino/schema`,并在多个函数签名中使用 `*schema.Document`(如 
`rag.go:38/110/143/...`);
   - `github.com/cloudwego/[email protected]/schema/message_parser.go:24` import 
sonic,并在 `:116`(`sonic.GetFromString`)、`:136`(`sonic.UnmarshalString`)实际调用;
   - `main.go:17/34` 注册 rag 组件,进入主程序构建图。
   
   Go 的构建模型是**包级编译**:只要一个包在依赖图中,就会被整体编译(与是否调用其函数无关),其中任何一个文件编译失败都会导致整个 `go 
build` 失败。因此 `go mod tidy` 也删不掉 sonic——它并非"孤儿依赖"。
   
   ### 2. Go 1.26 重写了 map 内部实现(Swiss Table)
   
   Go 1.26 将内置 map 改为基于 Abseil "Swiss Table" 
的实现(`$GOROOT/src/internal/runtime/maps/map.go:17-19`),runtime 侧 
`mapiterinit/mapiternext` 
的签名完全改变(`$GOROOT/src/runtime/linkname_shim.go:88/141`):
   
   ```go
   //go:linkname mapiterinit
   func mapiterinit(t *abi.MapType, m *maps.Map, it *linknameIter) { ... }
   ```
   
   即 map 类型从 `*hmap` 变为 `*maps.Map`,迭代器从 `*hiter` 变为 `*linknameIter`。官方保留 shim 
仅是为了兼容存量 `//go:linkname` 使用者(`linkname_shim.go:15-18` 注释明确说明),并不承诺布局稳定。
   
   ### 3. sonic v1.14.x 的 build tag 显式排除了 Go 1.26
   
   `//go:linkname` 是第三方库把本地函数直接链接到 runtime 未导出符号的机制,要求自建的数据结构与当前 Go 版本 runtime 
布局完全一致。sonic v1.14.1 用三个 build tag 文件按 Go 版本/实验开关"接力"定义 `GoMapIterator`:
   
   | 文件 | build tag | 生效范围 |
   |---|---|---|
   | `internal/rt/map_legacy.go:1` | `!go1.24` | Go < 1.24 |
   | `internal/rt/map_siwss_go124.go:1` | `go1.24 && !go1.26 && 
goexperiment.swissmap` | Go 1.24/1.25 + swissmap 实验 |
   | `internal/rt/map_nosiwss_go124.go:1` | `go1.24 && !go1.26 && 
!goexperiment.swissmap` | Go 1.24/1.25 默认 |
   
   三个文件都带 `!go1.26`(或等价的 `!go1.24`),**Go 1.26 下没有一个被编译** → `GoMapIterator` 
类型无定义 → `stubs.go:33/36` 的 linkname 声明编译失败。
   
   ### 4. 项目声明了 `go 1.24.11` 但没有锁定工具链
   
   `ai/go.mod` 第 3 行声明 `go 1.24.11`,但**没有 `toolchain` 指令**。`GOTOOLCHAIN=auto` 
的规则是:go.mod 版本 ≤ 当前工具链时直接使用当前工具链(不会自动降级)。因此在 Go 1.26.4 宿主机上构建时实际使用 1.26.4,与 
sonic v1.14.1 冲突。
   
   ### 5. 为什么 CI 没拦住
   
   主仓库 `.github/workflows/ci.yml` 只构建根模块(`go-version-file: go.mod`),`Makefile` 
与 CI 均未涉及 `ai/` 模块,因此该问题不会被现有 CI 发现。
   
   ---
   
   ## Proposed fix(解决方案)
   
   ### 方案 A(推荐):升级 `bytedance/sonic` 到 v1.15.0
   
   上游官方修复:PR bytedance/sonic#898(feat: support Go 1.26,改动 `rt: relink 
GoMapIterator` / `loader: add epclntab field` / 新的 `GoType.Indirect` 实现),随 
**v1.15.0** 发布。v1.15.0 新增 `internal/rt/map_go126.go`,build tag 为 `go1.26 || 
goexperiment.swissmap`,补齐 Go 1.26 下 `GoMapIterator` 的定义,且其 go.mod 仅要求 `go 
1.18`,不会抬高本模块版本。
   
   在 `ai/` 目录执行:
   
   ```bash
   go get github.com/bytedance/[email protected]
   go mod tidy
   ```
   
   预期连带升级:
   
   ```text
   github.com/bytedance/sonic v1.14.1 => v1.15.0
   github.com/bytedance/sonic/loader v0.3.0 => v0.5.0
   github.com/cloudwego/base64x => v0.1.6
   ```
   
   兼容性说明:`cloudwego/[email protected]` 自身要求 `sonic v1.14.1`(其 go.mod 第 6 
行),但这只是**最低版本**;Go 的 MVS(最小版本选择)会取主模块中更高的 v1.15.0,二者不冲突。
   
   **已验证**:在 /tmp 临时模块(`go 1.24.11` + `eino v0.7.34`,go1.26.4)中,升级前 `go build 
github.com/cloudwego/eino/schema` 复现 `undefined: GoMapIterator`;`go get 
github.com/bytedance/[email protected]` 后同一命令编译通过(exit 0)。下游项目(nuclei、homebrew-core 
等)也已用同样方式修复。
   
   ### 方案 B(可选):锁定工具链,兼容 `go 1.24.11` 声明
   
   在 `ai/go.mod` 增加 `toolchain go1.24.11` 指令,或在 CI/构建命令中固定 
`GOTOOLCHAIN=go1.24.11`,使 `GOTOOLCHAIN=auto` 自动下载并使用匹配工具链。此方案不改动依赖版本,但长期仍需跟进 
sonic 升级。
   
   ### 方案 C(临时规避):使用 Go 1.24 / 1.25 构建
   
   sonic v1.14.1 在 Go 1.24/1.25 下可正常编译,可作为升级前的临时规避手段。
   
   ---
   
   ## Impact(影响范围)
   
   - 阻塞:`ai/` 模块在 Go 1.26 环境下完全无法构建/启动(AI Agent 服务、RAG、SSE 对话链路)。
   - 触发面:任何使用 Go 1.26 工具链的开发/部署/CI 环境;Go 1.24/1.25 不受影响。
   - 修复成本:低(依赖升级,无业务代码改动)。
   
   ---
   
   ## References(参考)
   
   - 上游 issue:[bytedance/sonic#895 — Build with Go 1.26 fails: 
internal/rt/stubs.go: undefined: 
GoMapIterator](https://github.com/bytedance/sonic/issues/895)(确认 v1.14.0 与 
v1.14.2 均受影响)
   - 上游修复 PR:[bytedance/sonic#898 — feat: support Go 1.26 by 
AsterDY](https://github.com/bytedance/sonic/pull/898)
   - 发布版本:[bytedance/sonic 
v1.15.0](https://github.com/bytedance/sonic/releases/tag/v1.15.0)(含 Go 1.26 
支持;后续 issue #930 亦印证)
   - 
下游修复示例:[projectdiscovery/nuclei](https://github.com/projectdiscovery/nuclei/commit/2e1a81e6e9ce82b24173eebb7222ec068ddceff5)(bump
 sonic to 1.15.0 for Go 1.26 support)
   
   ---
   
   ## Logs
   
   <details><summary>Click me to check logs</summary>
   
   ```text
   $ cd ai
   $ go build .
   
   # github.com/bytedance/sonic/internal/rt
   
/opt/.tmp/.go-path/pkg/mod/github.com/bytedance/[email protected]/internal/rt/stubs.go:33:22:
 undefined: GoMapIterator
   
/opt/.tmp/.go-path/pkg/mod/github.com/bytedance/[email protected]/internal/rt/stubs.go:36:54:
 undefined: GoMapIterator
   ```
   
   关键定位信息:
   
   ```text
   $ go version
   go1.26.4 linux/amd64
   
   $ go mod why -m github.com/bytedance/sonic
   dubbo-admin-ai/component/rag
   github.com/cloudwego/eino/schema
   github.com/bytedance/sonic
   
   sonic v1.14.1 相关文件与 build tag:
     internal/rt/stubs.go:33/36      //go:linkname Mapiternext/Mapiterinit ... 
*GoMapIterator
     internal/rt/map_legacy.go:1     // +build !go1.24
     internal/rt/map_siwss_go124.go:1  // go1.24 && !go1.26 && 
goexperiment.swissmap
     internal/rt/map_nosiwss_go124.go:1 // go1.24 && !go1.26 && 
!goexperiment.swissmap
   
   Go 1.26 runtime($GOROOT/src):
     runtime/linkname_shim.go:88     func mapiterinit(t *abi.MapType, m 
*maps.Map, it *linknameIter)
     runtime/linkname_shim.go:141    func mapiternext(it *linknameIter)
     internal/runtime/maps/map.go:19  // Swiss Table 实现
   ```
   
   </details>
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to