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

主な診断指標

  • Model フィールド が、設定されたモデル(例: openai-codex/gpt-5.4)ではなく、リテラル文字列 discord/undefined と表示されている
  • Context フィールド が、実際の使用率ではなく 0/... と表示されている
  • Session フィールド が、updated just now ではなく no activity サフィックスを表示している
  • Session キー が、正しいチャンネルIDを持つ discord:channel:... ではなく discord/slash:... を参照している可能性がある

環境条件

  • OpenClaw バージョン: 2026.4.5(ビルド 3e72c03
  • インストール方法: npm global
  • オペレーティングシステム: 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 ネイティブコマンドパイプラインの2つの関数への変更が必要です:

修正 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)

合格基準:

  • Model フィールドが openai-codex/gpt-5.4 と表示されている(discord/undefined ではなく)
  • Context がゼロでないパーセンテージを表示している
  • Session キーが discord:channel:{channelId} を参照している
  • Session が 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:... ではなく)
  • Model フィールドが設定されたデフォルトモデルを表示している(discord/undefined ではなく)

テストケース 4: ギルドチャンネルとDMチャンネルの動作

実行: ギルドテキストチャンネルとDMチャンネルの両方で /status をテストします。

合格基準: 両方のチャンネルタイプで正しいチャンネルベースのセッションキーを持つ一貫したセッション解決動作が表示される必要があります。

自動検証スクリプト

#!/bin/bash
# Verify Discord native /status fix

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

# Capture /status output (requires Discord API or test harness)
STATUS_OUTPUT=$(get_discord_status_output)

# Check Model field
if echo "$STATUS_OUTPUT" | grep -q "Model: $EXPECTED_MODEL"; then
    echo "✓ Model field correct"
else
    echo "✗ Model field incorrect"
    exit 1
fi

# Check Session key format
if echo "$STATUS_OUTPUT" | grep -q "Session: $EXPECTED_SESSION_PREFIX"; then
    echo "✓ Session key correct"
else
    echo "✗ Session key incorrect"
    exit 1
fi

# Check for no-activity indicator should NOT be present
if echo "$STATUS_OUTPUT" | grep -q "• no activity"; then
    echo "✗ Still showing 'no activity' for active session"
    exit 1
else
    echo "✓ Activity status correct"
fi

echo "All verifications passed"

⚠️ よくある落とし穴

環境固有のトラップ

1. DMチャンネルとギルドチャンネル

  • 症状: 修正がギルドチャンネルでは動作するが、DMセッションで discord/undefined が表示される
  • 原因: DMチャンネルは異なるID形式やセッションキー構造を持っている可能性がある
  • 軽減策: セッションキー導出が channeldm の両方のプレフィックスを処理していることを確認する

2. チャンネルごとの複数のセッション

  • 症状: マルチエージェント設定でステータスが間違ったモデルのデータを表示する
  • 原因: チャンネルには異なるエージェントを持つ複数の同時セッションがある可能性がある
  • 軽減策: 修正はセッションキーの agent 次元を尊重する必要がある(例: agent:main:...

3. キャッシュされたルート状態

  • 症状: 修正は動作するように見えるが、ボット再起動後に元に戻る
  • 原因: メモリに古いルート状態がキャッシュされている可能性がある
  • 軽減策: セッションストアキャッシュをクリアするか、OpenClawプロセスを完全に再起動する

4. ネイティブコマンドとメッセージコマンドの競合

  • 症状: ネイティブとメッセージパスの両方の /status が不正なデータを表示する
  • 原因: ルート解決とは無関係にセッション Stor ルックアップが失敗している可能性がある
  • デバッグ: セッションストアにアクセス可能であり、ターゲットチャンネルのエントリが含まれていることを確認する

ユーザーの設定ミス

5. エージェント設定の欠落

  • 症状: 修正後もモデルが discord/undefined と表示される
  • 原因: ~/.openclaw/openclaw.json にデフォルトのエージェントモデルが設定されていない
  • 修正: agents.default.model が設定されていることを確認する:
{
  "agents": {
    "default": {
      "model": "openai-codex/gpt-5.4"
    }
  }
}

6. Discord ネイティブコマンドが有効になっていない

  • 症状: ネイティブ /status がネイティブコマンドパスを決して実行しない
  • 原因: Discord Developer Portal または OpenClaw設定でネイティブコマンドが無効になっている
  • 修正: Discordアプリ設定とOpenClaw設定の両方でネイティブコマンドを有効にする

7. 対話エンドポイントURLの設定ミス

  • 症状: ネイティブコマンドが汎用エラーを返すか、メッセージハンドラにフォールスルーする
  • 原因: 誤ったデプロイメントを指している不正な INTERACTIONS_ENDPOINT_URL
  • 修正: エンドポイントURLがデプロイされたOpenClawインスタンスと一致することを確認する

バージョン固有の考慮事項

8. ビルドハッシュの不一致

  • 症状: 修正が異なるハッシュサフィックスを持つファイルを参照しており、インストールされたバージョンと一致しない
  • 原因: バージョン 2026.4.5 には複数のビルドがある可能性がある
  • 確認: ステータス出力のビルドハッシュが修正対象の期待値と一致することを確認する

🔗 関連するエラー

論理的につながるエラーパターン

  • discord/undefined モデル表示 — ルート状態に依存する任意のコマンドパスでのセッションエントリ解決失敗の一般的な症状
  • no activity セッションステータス — セッションストアルックアップがnullまたは古いエントリを返したことを示す
  • unknown API キーインジケーター — セッションメタデータにprovider/key情報が欠落している場合の相関症状
  • スラッシュコマンドとメッセージコマンドの分岐 — Discord 対話タイプ間の不整合なルーティングに関連する

歴史的コンテキスト

  • セッショキーフォーマットの変更 (v2026.x) — 以前のバージョンでは異なるセッションキー構造を使用していた可能性があり、バージョンを混在させるとルックアップ失敗が発生する
  • ネイティブコマンド beta の制限 — ネイティブコマンド機能はbetaとしてメモかれており、このバグは不完全なセッションバインディング実装に関連する可能性がある
  • チャンネルとDMセッションの処理 — DMセッションが正しく永続化されないという以前の問題は、このバグと根本原因パターンを共有している可能性がある

関連するGitHubイシュー

  • ネイティブコマンドのセッションメタデータが欠落している — ネイティブコマンドコンテキスト伝播の一般的な追跡イシュー
  • Discord プロバイダのモデル解決 — Discord コマンドタイプ間でのプロバイダ固有のモデル解決失敗
  • ルート状態のライフサイクル管理 — 対話フェーズ全体でルート状態が適切に維持されない問題

関連する問題の診断コマンド

# Check session store contents
openclaw session list --filter discord

# Verify route resolution in debug mode
DEBUG=openclaw:route openclaw start

# Dump session entry for target channel
openclaw session dump agent:main:discord:channel:1490775030236450876

エビデンスとソース

このトラブルシューティングガイドは、FixClaw Intelligence パイプラインによってコミュニティの議論から自動的に合成されました。