INDEX に戻る🏠
障害レポート
発生日: 2026-07-26 報告日: 2026-07-27 対象: 結果報告機能 (v2) ステータス: 解決済

結果報告フロー: Quick Reply ラベル文字数超過

LINE Messaging API の Quick Reply ラベル 20文字制限により、NYA'sの結果報告操作が全件エラー

1 サマリー

9回
エラー発生
2名
影響ユーザー
解決済
7/27 デプロイ完了

2 影響

対象チーム

NYA(ニャース)の担当者 2名が、7/26 vs GXY(篠崎ゴールデンギャラクシー)戦の結果報告を実行できない状態が発生。

成績表(星取表)上のステータスが FIX のまま更新されず、結果が未記録となった。

影響期間

2026-07-26 14:03 〜 2026-07-27 デプロイ完了まで(約5時間20分 + 翌日対応分)

影響範囲

GXY(篠崎ゴールデンギャラクシー)を対戦相手とする全チームの結果報告が同様に失敗する状態だった。予定報告・その他チーム同士の結果報告は正常に動作。

根本原因: handleResultModeV2 で生成する Quick Reply のラベルが LINE API の 20文字制限を超過。GXY のチーム名「篠崎ゴールデンギャラクシー」(13文字)と日付・"vs" を結合すると 21文字以上になり、API が 400 エラーを返した。

3 発生経緯

NYA 担当者 A(U774c...)が 14:02 に操作開始。予定報告は正常完了したが、結果報告は全て同一エラーで失敗。19:21 に別の担当者 B(Ua615...)も同じエラーに遭遇。

14:02:19
担当者A「予定報告」送信 → 正常に処理
14:02:22
「結果報告」送信 → 400 ERROR
結果報告モード開始直後、試合選択の Quick Reply 送信時に LINE API がエラーを返却
14:02:37 〜 14:02:52
「予定報告」→ GXY選択 → 日付選択(7/26)→ 正常完了
予定報告フローでは Quick Reply ラベルがチーム名のみ(13文字)のため制限内
14:03 〜 14:17
「結果報告」を計 5回リトライ → 全て同一エラー
14:07 にメッセージ取消操作あり。その後も再試行を繰り返すが解消せず
19:21 〜 19:23
担当者B「結果報告」を計 3回リトライ → 全て同一エラー
予定報告 → GXY選択は成功するが、結果報告に切り替えると即座にエラー
翌 7/27
NYA's 担当者から「結果報告ができない」と相談 → 調査開始

4 原因分析

根本原因: LINE Messaging API の Quick Reply ラベルには 20文字以内 の制約がある。handleResultModeV2 が生成するラベル 日付 + " vs " + チーム名 + (N戦目) が、GXY のフル名称で 21文字以上となり制限を超過した。

ラベル文字数の検証

対戦相手ラベル例文字数結果
ニャース (NYA)7/26 vs ニャース12OK
江戸川ポーザーズ (EPS)7/26 vs 江戸川ポーザーズ16OK
篠崎ゴールデンギャラクシー (GXY)7/26 vs 篠崎ゴールデンギャラクシー21超過
江戸川ポーザーズ(2戦目)7/26 vs 江戸川ポーザーズ (2戦目)22超過

GXY は 1戦目でも超過する唯一のチーム。EPS は 2戦目以降で超過する。その他のチームは全パターンで制限内。

エラー箇所

main_v2.gshandleResultModeV2 関数(117〜127行目)で、Quick Reply ラベルを無制限に結合していた。

// main_v2.gs — handleResultModeV2 内 var oppName = TEAM_NAME_MAP[m.oppCode] || m.oppCode; var suffix = (m.matchNum > 1) ? " (" + m.matchNum + "戦目)" : ""; return { label: dateStr + " vs " + oppName + suffix, // ← 20文字を超える可能性 data: "f=rep&opp=" + m.oppCode + "&mid=" + m.matchId };

LINE API は Quick Reply の label が 20文字を超えるとリクエスト全体を 400 で拒否するため、試合選択画面自体が表示されなかった。

エラーレスポンス

HTTP 400 { "message": "The request body has 1 error(s)", "details": [{ "message": "`label` must not be longer than 20 characters", "property": "messages[0].quickReply.items[N].action.label" }] }

5 修正内容

修正ファイル

ファイル関数変更内容
main_v2.gs handleResultModeV2 ラベルが 20文字超の場合、チーム名をチームコード(3文字)に短縮。displayText にフル名称を設定
function.gs sendQuickReply displayText プロパティのサポートを追加

修正ロジック: main_v2.gs

ラベルが20文字を超える場合、チーム名をコード(GXY 等)に置き換えてから、さらに超過する場合は 20文字で切り詰め。ユーザーのチャット画面には displayText 経由でフル名称を表示。

var fullLabel = dateStr + " vs " + oppName + suffix; var shortLabel = fullLabel.length > 20 ? dateStr + " vs " + m.oppCode + suffix // コード(3文字)に短縮 : fullLabel; if (shortLabel.length > 20) { shortLabel = shortLabel.substring(0, 20); // 最終安全弁 } return { label: shortLabel, // Quick Reply ボタンに表示(20文字以内) displayText: fullLabel, // タップ後のチャットに表示(制限なし) data: "f=rep&opp=" + m.oppCode + "&mid=" + m.matchId };

修正ロジック: function.gs

sendQuickReplydisplayText を受け取れるよう、action オブジェクトの displayTextopt.displayText || opt.label に変更。

// function.gs — sendQuickReply 内 action: { type: "postback", label: opt.label, data: opt.data, displayText: opt.displayText || opt.label // ← 追加 }

Before

ボタン表示とチャット表示が同一の label を使用。

GXY 対戦時: 21文字超過 → 400エラー

After

ボタン: 7/26 vs GXY(12文字)
チャット: 7/26 vs 篠崎ゴールデンギャラクシー

20文字以内を保証

6 デプロイ

項目内容
デプロイ日時2026-07-27
対象ファイルmain_v2.gs, function.gs
デプロイ方法GAS エディタへ手動コピー → Webhook URL 更新
確認結果正常動作確認済

7 再発防止

対策: 今回の修正で Quick Reply ラベルは常に 20文字以内に収まるよう 2段階の安全弁(コード短縮 → substring 切り詰め)を組み込んだ。全チーム・全パターン(複数戦目、10〜12月の日付)で制限内であることを確認済み。

今後の検討事項