type guard 1つ、PR 1本、merge 1回。ユーザーからcontributorへ。

OpenClawを使い始めて、もうしばらく経ちます。毎日Pinguとterminal内で共同作業しています。記事を書き、projectを管理し、cronを走らせ、健康dataを整理する。デジタル生活の半分はOpenClawの中で進んでいます。

長く使うと、自然に端のbugを踏みます。

Bugに出会う

このbugはTelegram統合部分にありました。OpenClawにはdescribeReplyTargetという関数があります。Telegram messageのreply context、つまり返信先messageの内容を解析する役割です。

問題は、Telegram APIが返すreplyLike.textが常に文字列とは限らないことでした。ときにはExternalReplyInfo objectになることがあります。ところが元のcodeは、それに直接.trim()を呼んでいました。

const rawText = replyLike.text ?? replyLike.caption ?? "";
return rawText.trim(); // rawTextがobjectなら → TypeError

objectには.trim() methodがないので、そのままTypeErrorで落ちます。

修正

修正は単純で、type guard 1つです。

const rawText = replyLike.text ?? replyLike.caption ?? "";
const safeText = typeof rawText === "string" ? rawText.trim() : "";

同じ関数内で、quoteTextはすでにまったく同じpatternを使っていました。今回の変更は、既存の防御logicを漏れていた場所に足しただけです。

ついでにregression testも追加し、文字列ではない値で再び落ちないことを確認しました。

// text: { some: "object" } を渡す → throwではなくnullを返すべき

PR提出

PR #50500、titleは次の通りです。

fix(telegram): add type guard for reply context text

提出後、Greptile(自動code review bot)は 5/5 confidence を出しました。

“This PR is safe to merge: the change is minimal, correct, and well-tested.”

Maintainerの@obviyusは3/23にそのままmainへmergeし、一言残しました。

“Thanks @p3nchan.”

修正の往復も、request changesもありません。一発で入りました。

感想

これは、規模のあるopen source projectへ出したPRがmergeされた初めての経験です。

変更は小さいです。type guard 1つ、数行のcodeだけです。でも「ユーザー」から「contributor」へ変わる感覚は、codeそのものよりずっと大きく感じました。

よいopen source contributionは、たいていこういうものです。日常で問題に気づき、熱が残っているうちにそのまま直す。大きなrefactorよりずっと実際的です。

毎日使っているtoolの中には、直されるのを待っている小さなbugがあるかもしれません。

真面目に遊び、ゆっくり進む。

関連記事


こぺんぎんの体験談

OpenClawは毎日使う中心的なtoolです。記事作成、project管理、cron実行までかなり頼っています。長く使うと、端のbugには自然に当たります。今回のTelegram reply contextのtype問題も、日常利用の中で発火しました。規模のあるopen source projectへの初PRは、もっと何度も修正することになると思っていましたが、一発で入りました。自分が実際に使うものをそのまま直す道は、思ったより滑らかでした。

よくある質問

Q: OpenClawとは何ですか?

OpenClawはopen sourceのAI CLI toolです。terminal上でAIとやり取りし、code実行、ファイル管理、workflow自動化ができます。

Q: このPRは何を直しましたか?

Telegram platform上のreply context textで起きるruntime errorを直しました。APIが文字列ではない値を返したとき、元の.trim()がそのまま落ちていたため、type guardを追加して解決しました。

Q: 初めてopen source projectに貢献するのは難しいですか?

難しくはありません。ただし、正しい入り口を見つける必要があります。自分が実際に踏んだbugから始めると、修正も自然で、reviewerにも動機が伝わりやすいです。


— Penchan