April 22, 2026 • 版本: 2026.4.5

[原生 Discord /status 命令显示 'discord/undefined' 且活动频道会话无活动] - Discord Native /status Reports 'discord/undefined' and No Activity for Active Channel Sessions

原生 Discord /status 命令错误地显示 Model: discord/undefined、零上下文和即使在有效频道会话激活时也无活动。根本原因是原生命令路由路径中缺少 sessionEntry 查找。

🔍 症状

用户可见的表现

在带有活动会话的频道中执行原生的 Discord /status 命令时,返回以下错误输出:

🦞 OpenClaw 2026.4.5 (3e72c03)
🧠 Model: discord/undefined · 🔑 unknown
📚 Context: 0/200k (0%) · 🧹 Compactions: 0
🧵 Session: agent:main:discord:slash:332887877048598528 • no activity
📌 Tasks: 0 active · 5 total · agent-local
⚙️ Runtime: direct · Think: off · elevated
🪢 Queue: collect (depth 0)

在某些观察中,会话键显示正确的频道 ID,但元数据仍然不正确:

🧵 Session: agent:main:discord:channel:1490775030236450876 • no activity

与正常消息路径状态的对比

当通过正常消息路径查询同一频道的会话时(在常规消息中追加 /status),输出是正确的:

🦞 OpenClaw 2026.4.5 (3e72c03)
🧠 Model: openai-codex/gpt-5.4 · 🔑 oauth (...)
📚 Context: 50k/272k (18%)
🧵 Session: agent:main:discord:channel:1490775030236450876 • updated just now

关键诊断指标

  • 模型字段显示字面字符串 discord/undefined,而不是配置的模型(例如 openai-codex/gpt-5.4
  • 上下文字段显示 0/...,而不是实际使用百分比
  • 会话字段显示 no activity 后缀,而不是 updated just now
  • 会话键可能引用 discord/slash:... 而不是带有正确频道 ID 的 discord:channel:...

环境条件

  • OpenClaw 版本:2026.4.5(构建版本 3e72c03
  • 安装方式:npm 全局安装
  • 操作系统:Linux 5.15.0-171-generic (x64)
  • Discord 模式:启用原生命令的服务器频道
  • 默认代理模型:openai-codex/gpt-5.4

🧠 根因分析

架构分析

该缺陷源于原生 Discord 命令路由管道中缺少会话条目解析。原生的 /status 命令代码路径尝试读取 routeState.sessionEntry 以填充状态元数据,但此属性从未被上游路由解析函数填充。

代码流程分解

1. 入口点:原生命令调用

当用户将 /status 作为 Discord 原生(斜杠)命令调用时,请求进入:

provider-DR2mO1YM.js → commands.runtime-CVX5D6kT.js → pi-embedded-DWASRjxE.js → status-yaHSTeGo.js

2. 会话解析失败

provider-DR2mO1YM.js 中,原生 /status 分支引用 routeState.sessionEntry

// 问题代码路径的伪代码表示
const routeState = resolveDiscordNativeInteractionRouteState(interaction);
const sessionEntry = routeState.sessionEntry; // ← 此处为 UNDEFINED

if (!sessionEntry) {
    // 回退到斜杠负载元数据
    displayStatus(slashPayloadMetadata);
}

3. 路由状态解析缺口

函数 resolveDiscordNativeInteractionRouteState() 返回:

{
    route: "...",           // ✓ 已提供
    effectiveRoute: "...",   // ✓ 已提供
    binding: {...},         // ✓ 已提供
    sessionEntry: undefined  // ✗ 缺失
}

该函数提供路由元数据(route、effectiveRoute、binding),但从不填充 sessionEntry,使其保持为 undefined

4. 使用硬编码回退值构建上下文

sessionEntry 为 undefined 时,buildDiscordNativeCommandContext() 使用缺失的数据执行。此函数:

  • 硬编码提供者作为字面字符串 "discord"
  • 无法解析代理配置中的实际配置模型
  • 无法查询会话存储中的活动频道会话

5. 级联失败到状态显示

状态渲染引擎收到:

{
    provider: "discord",
    model: undefined,       // 导致 "discord/undefined"
    contextUsage: 0,        // 导致 "0/200k (0%)"
    sessionKey: "discord/slash:..." // 错误的会话类型
}

为什么消息路径可以正常工作

正常消息路径的状态查询使用不同的代码路径,该路径:

  1. 从消息上下文中解析频道 ID
  2. 直接查询会话存储以获取 agent:main:discord:channel:{channelId}
  3. 从存储的会话条目中提取实际模型、上下文使用率和最后活动时间戳

此路径完全绕过了有问题的 resolveDiscordNativeInteractionRouteState() 函数。

会话键差异解释

会话键显示 discord/slash:{interactionId} 而不是 discord:channel:{channelId},原因如下:

  • 回退路径使用交互的命令 ID 作为会话标识符
  • 它从不解析到父频道的会话条目
  • 正确的路径应从交互的频道上下文中派生频道 ID

🛠️ 逐步修复

临时解决方案(立即生效)

在修复部署之前,使用消息路径状态查询:

之前(损坏 - 原生命令):

/status

之后(正常 - 消息路径):

任意消息内容 /status

这会强制使用消息路由路径,该路径可以正确解析频道会话。

永久修复(面向维护者)

修复需要修改 Discord 原生命令管道中的两个函数:

修复 1:在路由解析中填充 sessionEntry

文件: provider-DR2mO1YM.js(或等效捆绑包)

修复前:

function resolveDiscordNativeInteractionRouteState(interaction) {
    return {
        route: determineRoute(interaction),
        effectiveRoute: determineEffectiveRoute(interaction),
        binding: resolveBinding(interaction)
        // sessionEntry 缺失
    };
}

修复后:

function resolveDiscordNativeInteractionRouteState(interaction) {
    const channelId = interaction?.channel_id || interaction?.channelId;
    const sessionKey = channelId 
        ? `agent:main:discord:channel:${channelId}`
        : null;
    
    return {
        route: determineRoute(interaction),
        effectiveRoute: determineEffectiveRoute(interaction),
        binding: resolveBinding(interaction),
        sessionEntry: sessionKey ? sessionStore.get(sessionKey) : null
    };
}

修复 2:在状态上下文中处理缺失的模型

文件: buildDiscordNativeCommandContext 函数

修复前:

function buildDiscordNativeCommandContext(sessionEntry) {
    return {
        provider: "discord",
        model: sessionEntry?.model || undefined,
        // ...
    };
}

修复后:

function buildDiscordNativeCommandContext(sessionEntry, routeState) {
    // 如果 routeState 中缺少 sessionEntry,尝试直接查询
    const resolvedSession = sessionEntry || (
        routeState?.binding?.channelId 
            ? sessionStore.get(`agent:main:discord:channel:${routeState.binding.channelId}`)
            : null
    );
    
    return {
        provider: resolvedSession?.provider || "discord",
        model: resolvedSession?.model || getDefaultAgentModel(),
        // ...
    };
}

修复 3:为状态显示派生正确的会话键

文件: status-yaHSTeGo.js(状态渲染)

修复前:

function resolveStatusSessionKey(routeState) {
    if (routeState.sessionEntry) {
        return routeState.sessionEntry.key;
    }
    return `discord/slash:${interaction.id}`;
}

修复后:

function resolveStatusSessionKey(routeState) {
    if (routeState.sessionEntry) {
        return routeState.sessionEntry.key;
    }
    // 回退到基于频道的键,而不是斜杠交互 ID
    const channelId = routeState.binding?.channelId;
    return channelId 
        ? `agent:main:discord:channel:${channelId}`
        : `discord/slash:${interaction.id}`;
}

🧪 验证

测试用例 1:活动频道会话中的原生命令状态

设置:

  • 确保存在已知频道 ID(例如 1490775030236450876)的会话
  • 验证会话具有非零上下文使用率

执行:

/status

预期输出:

🦞 OpenClaw 2026.4.5 (3e72c03)
🧠 Model: openai-codex/gpt-5.4 · 🔑 oauth (...)
📚 Context: 50k/272k (18%)
🧵 Session: agent:main:discord:channel:1490775030236450876 • updated just now
📌 Tasks: 0 active · 5 total · agent-local
⚙️ Runtime: direct · Think: off · elevated
🪢 Queue: collect (depth 0)

通过标准:

  • 模型字段显示 openai-codex/gpt-5.4(不是 discord/undefined
  • 上下文显示非零百分比
  • 会话键引用 discord:channel:{channelId}
  • 会话显示 updated just now(不是 no activity

测试用例 2:与消息路径状态的对比

执行:

What's the current status? /status

验证: 原生命令输出和消息路径输出应显示相同的内容:

  • 模型名称
  • 上下文百分比
  • 会话键
  • 最后活动的时间戳

测试用例 3:新会话状态(无活动频道会话)

设置: 在没有先前会话的频道中调用 /status

预期输出:

🧵 Session: agent:main:discord:channel:{channelId} • no activity

通过标准:

  • 会话键仍然显示 discord:channel:{channelId}(不是 discord/slash:...
  • 模型字段应显示配置的默认模型(不是 discord/undefined

测试用例 4:服务器频道与 DM 频道的行为

执行: 在服务器文本频道和 DM 频道中测试 /status

通过标准: 两种频道类型应显示一致的会话解析行为,具有正确的基于频道的会话键。

自动化验证脚本

#!/bin/bash
# 验证 Discord 原生 /status 修复

EXPECTED_MODEL="openai-codex/gpt-5.4"
CHANNEL_ID="1490775030236450876"
EXPECTED_SESSION_PREFIX="agent:main:discord:channel:${CHANNEL_ID}"

# 捕获 /status 输出(需要 Discord API 或测试工具)
STATUS_OUTPUT=$(get_discord_status_output)

# 检查模型字段
if echo "$STATUS_OUTPUT" | grep -q "Model: $EXPECTED_MODEL"; then
    echo "✓ 模型字段正确"
else
    echo "✗ 模型字段不正确"
    exit 1
fi

# 检查会话键格式
if echo "$STATUS_OUTPUT" | grep -q "Session: $EXPECTED_SESSION_PREFIX"; then
    echo "✓ 会话键正确"
else
    echo "✗ 会话键不正确"
    exit 1
fi

# 检查是否仍存在无活动指示器
if echo "$STATUS_OUTPUT" | grep -q "• no activity"; then
    echo "✗ 对于活动会话仍显示 'no activity'"
    exit 1
else
    echo "✓ 活动状态正确"
fi

echo "所有验证通过"

⚠️ 常见陷阱

环境特定的陷阱

1. DM 频道与服务器频道

  • 症状:修复在服务器频道中有效,但 DM 会话显示 discord/undefined
  • 原因:DM 频道可能具有不同的 ID 格式或会话键结构
  • 缓解措施:确保会话键派生同时处理 channeldm 前缀

2. 每个频道的多个会话

  • 症状:状态显示多代理设置下错误模型的数据
  • 原因:频道可能具有不同代理的多个并发会话
  • 缓解措施:修复应尊重会话键中的 agent 维度(例如 agent:main:...

3. 缓存的路由状态

  • 症状:修复似乎有效,但在机器人重启后恢复
  • 原因:旧的路由状态可能缓存在内存中
  • 缓解措施:清除会话存储缓存或完全重启 OpenClaw 进程

4. 原生命令与消息命令冲突

  • 症状:原生和消息路径 /status 都显示不正确的数据
  • 原因:会话存储查询可能独立于路由解析而失败
  • 调试:验证会话存储可访问且包含目标频道的条目

用户配置错误

5. 缺少代理配置

  • 症状:即使修复后,模型仍显示 discord/undefined
  • 原因:~/.openclaw/openclaw.json 中未配置默认代理模型
  • 修复:确保设置 agents.default.model
{
  "agents": {
    "default": {
      "model": "openai-codex/gpt-5.4"
    }
  }
}

6. Discord 原生命令未启用

  • 症状:原生 /status 从不执行原生命令路径
  • 原因:在 Discord 开发者门户或 OpenClaw 配置中禁用了原生命令
  • 修复:在 Discord 应用设置和 OpenClaw 配置中启用原生命令

7. 交互端点 URL 配置错误

  • 症状:原生命令返回通用错误或回退到消息处理器
  • 原因:错误的 INTERACTIONS_ENDPOINT_URL 指向错误的部署
  • 修复:验证端点 URL 与部署的 OpenClaw 实例匹配

版本特定注意事项

8. 构建哈希不匹配

  • 症状:修复引用的文件具有与安装版本不同的哈希后缀
  • 原因:版本 2026.4.5 可能具有多个构建版本
  • 验证:确认状态输出中的构建哈希与预期的修复目标匹配

🔗 相关错误

逻辑上相关的错误模式

  • discord/undefined 模型显示 — 依赖路由状态的任何命令路径上会话条目解析失败的通用症状
  • no activity 会话状态 — 表示会话存储查询返回 null 或过时条目
  • unknown API 密钥指示器 — 会话元数据缺失提供程序/密钥信息时的相关症状
  • 斜杠命令与消息命令差异 — 与 Discord 交互类型之间路由不一致相关

历史背景

  • 会话键格式更改 (v2026.x) — 早期版本可能使用不同的会话键结构,在混合版本时导致查询失败
  • 原生命令测试版限制 — 原生命令功能被标记为测试版;此缺陷可能与不完整的会话绑定实现相关
  • 频道与 DM 会话处理 — DM 会话不正确持久化的先前问题可能与此缺陷共享根因模式

相关 GitHub 问题

  • 原生命令的会话元数据缺失 — 原生命令上下文传播的通用跟踪问题
  • Discord 提供程序的模型解析 — Discord 命令类型之间的提供程序特定模型解析失败
  • 路由状态生命周期管理 — 路由状态在交互阶段之间未正确维护的问题

相关问题的诊断命令

# 检查会话存储内容
openclaw session list --filter discord

# 在调试模式下验证路由解析
DEBUG=openclaw:route openclaw start

# 导出目标频道的会话条目
openclaw session dump agent:main:discord:channel:1490775030236450876

依据与来源

本故障排除指南由 FixClaw 智能管线从社区讨论中自动合成。