关于 walrus-troubleshooting
walrus-troubleshooting 是面向 Walrus 开发者的故障排查技能,按工具整理 CLI、SDK、API、Move、Seal 和网络错误,并说明原因与处理方法。
主要功能
- 01按工具分类错误
- 02说明问题原因与修复方法
- 03涵盖 CLI、TypeScript SDK 和 HTTP API
- 04排查 Move、Seal 与网络问题
适用场景
- 01诊断 Walrus CLI 配置或上传错误
- 02处理 TypeScript SDK Blob 写入或中继故障
- 03排查 HTTP API 和聚合器响应
- 04检查 Move 依赖或网络版本错误
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mystenlabs/ walrus-skills --skill walrus-troubleshooting安装后在 Claude Code 中输入/walrus-troubleshooting确认已加载。
附带文件evals/evals.json
详细介绍
Walrus 故障排查
来源约束: 本技能中的所有错误均来自 Walrus 文档、Walrus 仓库 或 TypeScript SDK 源代码。 扩充内容时,只有注明错误所来自的页面或源文件,才能添加该错误。
本技能汇总了用户使用 Walrus 时最常遇到的错误,并按工具分类。每项均包含错误消息、原因和解决方法。
相关技能
| 主题 | 技能 | 加载时机 |
|---|---|---|
| CLI | walrus-cli | CLI 使用和配置 |
| TypeScript SDK | walrus-ts-sdk | SDK 初始化和使用 |
| HTTP API | walrus-http-api | REST 端点使用 |
| Move 集成 | walrus-move-integration | Move 依赖和合约问题 |
| 存储成本 | walrus-storage-costs | 成本相关问题 |
| 概览 | walrus-overview | 术语混淆(blob ID 与 object ID 等) |
技能内容
CLI 错误
spawn walrus ENOENT 或 command not found: walrus
原因: 未安装 walrus 二进制文件,或其不在 PATH 中。
解决方法:
curl -sSfL https://raw.githubusercontent.com/Mystenlabs/suiup/main/install.sh | sh
suiup install walrus
如果已安装,请将 ~/.suiup/bin 添加到 PATH。安装后重新启动 shell。
Cannot find gas coin for signer address
原因: 钱包中没有 SUI 代币。Walrus 操作需要 SUI 支付 Gas 费。
解决方法:
- Testnet: 运行
sui client faucet获取测试用 SUI。 - Mainnet: 通过交易所获取 SUI,并转入钱包地址。
使用 sui client gas 检查余额。
could not find a valid Walrus configuration file
原因: CLI 找不到 client_config.yaml。
解决方法:
curl --create-dirs https://docs.wal.app/setup/client_config.yaml \
-o ~/.config/walrus/client_config.yaml
或者显式指定路径:walrus --config /path/to/client_config.yaml store ...
blobs can only be stored for up to MAX_EPOCHS epochs ahead
原因: 请求的存储时长超过上限。当前上限为 53 个 epoch;walrus info 会报告该值。
解决方法: 使用 --epochs 53 或 --epochs max,并计划在到期前延长存储期限。
exactly one of epochs, earliest-expiry-time, or end-epoch must be specified
原因: walrus store 未指定这三个期限选项中的任何一个,或指定了多个。
解决方法: 必须且只能传入一个选项:--epochs <N|max>、--earliest-expiry-time <TIME> 或 --end-epoch <N>。
deletable blobs cannot be shared
原因: walrus share 收到的是可删除的 blob。共享的 blob 必须是永久存储的。
解决方法: 使用 --permanent(或 --permanent --share)存储,然后共享该 blob。
The object ID of an exchange object must be specified ... this command is only available on Testnet
原因: walrus get-wal 在 Mainnet 上下文中运行,而该上下文未声明任何兑换对象。
解决方法: get-wal 仅适用于 Testnet(walrus get-wal --context testnet)。在 Mainnet 上,请通过交易所获取 WAL,或从持有 WAL 的地址转入。
上传偶尔失败,但配置没有变化
原因: 存储节点不可达,而非客户端问题。写入需要 n - f 个分片(1,000 个中需 667 个);当健康分片数量刚好高于该值时,只要写入所需的节点落入不可达集合,单次尝试就会失败。
解决方法:
walrus health --committee --sort-by status # which nodes are in Error
walrus info bft # the write threshold n - f
健康分片数远高于 n - f:正常上传。刚刚高于该值:预计会偶尔失败,请重试。低于该值:写入无法通过认证;请等待网络恢复,而不是反复重试。读取在分片数降至 n - 2f 时仍可正常工作。
Testnet 上的 blob 很快消失
原因: Testnet 的 epoch 比 Mainnet 短。以较小的 epoch 数存储,会导致 blob 比预期更早过期。
解决方法: 使用 walrus info 查看当前 epoch 时长。在 Testnet 上使用较大的 epoch 数(30 个以上)。在 Mainnet 上,1 个 epoch = 14 天。
TypeScript SDK 错误
ChainNotSupportedError: The account does not support the chain "sui:undefined"
原因: dApp Kit 钱包适配器未配置正确的网络。SDK 无法确定要使用哪个 Sui 链。
解决方法: 确保 dApp Kit 提供程序指定了链:
<SuiClientProvider networks={{ testnet: { url: getFullnodeUrl('testnet') } }} defaultNetwork="testnet">
并确保钱包连接到同一网络。
file.bytes is not a function
原因: 将原始字符串或 JavaScript 对象作为 blob 传入,而不是二进制数据。
解决方法: 先转换为 Uint8Array:
// WRONG
await client.walrus.writeBlob({ blob: myJsonString, epochs: 5, deletable: true, signer });
// CORRECT
await client.walrus.writeBlob({
blob: new TextEncoder().encode(myJsonString),
epochs: 5,
deletable: true,
signer,
});
// Or use the WalrusFile API, which accepts a Uint8Array, Blob, or string
const file = WalrusFile.from({ contents: myJsonString, identifier: 'data.json' });
await client.walrus.writeFiles({ files: [file], epochs: 5, deletable: true, signer });
writeBlob 接受 Uint8Array。@mysten/walrus 中没有 storeBlob 方法。
Tip amount (N) exceeds the maximum allowed tip (M)
原因: 上传中继要求的 tip 高于你配置的最大值。对于你正在使用的中继,默认的 sendTip.max 值过低。
解决方法: 提高上传中继配置中的 sendTip.max 值:
uploadRelay: {
host: 'https://upload-relay.mainnet.walrus.space',
sendTip: { max: 5_000_000 }, // increase as needed
},
查看中继要求的 tip:curl <relay-url>/v1/tip-config
RetryableWalrusClientError: Too many failures while writing blob
原因: SDK 未能将 sliver 分发到足够多的存储节点。常见原因:
- 在浏览器环境中未配置上传中继
- 与存储节点之间的网络连接出现问题
- 存储节点暂时不可用
解决方法:
- 在浏览器中配置上传中继(参见
walrus-ts-sdk技能)。 - 检查网络连接。
- 使用指数退避进行重试。
- 如果问题持续存在,请尝试使用其他上传中继,或等待存储节点恢复。
- 在 epoch 变更前后,客户端缓存的委员会可能会过期:
if (error instanceof RetryableWalrusClientError) { client.walrus.reset(); /* retry */ }。传入storageNodeClientOptions: { onError },即可查看 SDK 忽略的各个节点错误。
BlobNotCertifiedError
原因: blob 已在链上注册,但尚未收到足够多存储节点的确认。可用性证书尚未提交。
解决方法: blob 尚未达到其可用性证明(PoA)状态。请等待认证完成。如果认证始终未完成,则上传可能在中途失败。请重试存储操作。
Vite、Next.js 或其他打包工具无法加载 SDK 的 WASM 模块
原因: SDK 需要 WASM 绑定来编码和解码 blob,而打包工具在运行时无法定位二进制文件(Turbopack 会将其显示为 /ROOT/... 这样的虚拟化路径)。
解决方法: 告知客户端 WASM 文件的位置:
// Vite: import the file with ?url and pass it as wasmUrl
import walrusWasmUrl from '@mysten/walrus-wasm/web/walrus_wasm_bg.wasm?url';
const client = new SuiGrpcClient({ network: 'testnet', baseUrl: 'https://fullnode.testnet.sui.io:443' })
.$extend(walrus({ wasmUrl: walrusWasmUrl }));
// Or a CDN / self-hosted copy
walrus({ wasmUrl: 'https://unpkg.com/@mysten/walrus-wasm@latest/web/walrus_wasm_bg.wasm' });
// Next.js API routes (webpack and Turbopack)
const nextConfig: NextConfig = { serverExternalPackages: ['@mysten/walrus', '@mysten/walrus-wasm'] };
HTTP API 错误
413 Payload Too Large
原因: 发布器对请求正文大小设有限制。公共测试网发布器将上传大小限制在约 10 MiB。
解决方法:
- 对于超过发布器限制的文件,请使用 CLI、TypeScript SDK,或运行自己的发布器。
- 主网上没有公共发布器。请直接使用上传中继或 SDK。
聚合器返回 503 BLOB_UNAVAILABLE
原因: blob 只是暂时无法检索(自 v1.47 起,聚合器对此返回可重试的 503,而不是 500)。
解决方法: 使用指数退避进行重试。如果问题持续存在,请检查 walrus blob-status --blob-id <BLOB_ID>:blob 可能已过期,或从未通过认证。
上传后立即出现 404 Not Found
原因: 聚合器上的 CDN 缓存。聚合器的 CDN 缓存了 blob 传播之前产生的 404。
解决方法: 使用指数退避进行重试。认证后,blob 应在几秒到几分钟内变为可用状态。如果使用的是由 CDN 提供服务的聚合器,缓存 TTL 决定了延迟时间。
Move 集成错误
VMVerificationOrDeserializationError in command 0
**原因:**已发布的 Move 包与链上的 Walrus 合约不匹配。这几乎总是 Move.toml 依赖问题。
**修复方法:**按以下顺序检查:
-
**网络对应的
subdir错误。**测试网使用testnet-contracts/walrus,主网使用contracts/walrus。# Testnet Walrus = { git = "https://github.com/MystenLabs/walrus.git", rev = "testnet", subdir = "testnet-contracts/walrus" } # Mainnet Walrus = { git = "https://github.com/MystenLabs/walrus.git", rev = "main", subdir = "contracts/walrus" } -
**
rev错误。**提交必须与链上部署的版本一致。测试网使用testnet分支,主网使用main分支,或者固定到特定提交。 -
**
Move.lock已过期。**删除Move.lock并重新构建:rm Move.lock && sui move build。 -
**
edition错误。**使用edition = "2024",而不是"2024.beta"。使用 2024 版时,Sui 框架会隐式解析;显式指定与 Walrus 包框架版本不匹配的Sui = { git = ... }会导致依赖解析错误。请移除它。
system::inner_mut 返回 EWrongVersion(中止代码 1)
**原因:**Walrus 升级后,使用旧包 ID 调用 Walrus 系统函数。Walrus 使用带版本的共享对象。
修复方法:
- **如果使用 CLI 或 SDK:**更新到最新版本。客户端会自动刷新包 ID。
- **如果直接调用合约:**查询
system_object以查找当前包 ID。不要硬编码包 ID。 - Walrus 客户端代码内置了重试逻辑:遇到
EWrongVersion时,会调用refresh_package_id()并重试。
Seal 错误
Transaction was not signed by the correct sender
**原因:**传递给 Seal 的 PTB 未设置 tx.setSender(address),或者发送方与解密地址不匹配。
修复方法:
tx.setSender(address); // Must match the decrypting wallet address
网络 / 常见错误
client/server api version mismatch
**原因:**已安装的 walrus 二进制版本与网络预期版本不匹配。
修复方法:
suiup update walrus
# or install the version matching your network
suiup install walrus@mainnet
规则
- 遇到 Move 错误时,先检查
Move.toml。VMVerificationOrDeserializationError几乎总是依赖问题。 - **遇到“gas coin”错误时,检查代币余额。**写入操作需要 SUI 和 WAL。
- **为浏览器应用配置上传中继。**在浏览器中使用 SDK 执行写入操作需要上传中继。
- **切换依赖修订版本时,删除
Move.lock。**过期的锁文件会导致构建失败。 - **使用
walrus info验证网络连接和配置。**如果walrus info可以正常运行,则配置正确。 - **看到版本不匹配错误时,更新 CLI。**运行
suiup update walrus。