SQLiteのLIKEパターンにおける隠れた50バイト制限により、Agentic Inboxプロジェクトが長いメール件名を検索しようとした際にCloudflare Workersがクラッシュしました。検索文字列を48文字に制限することで、このエラーは解消されました。

エッジランタイムを破壊したもの

Agentic Inboxは、各メールボックスをCloudflare Durable Object内で実行し、ストレージとして組み込みのSQLiteデータベースを使用しています。AI駆動のエージェントは、検索パターンを %search_term% の形式で構築します。SQLiteは、LIKEパターンの総長に対して50バイトという厳格な上限を設けています。ユーザーが48文字を超える件名を入力すると、前後の % 記号によってパターンがその上限を超えてしまいました。SQLiteは未処理のランタイムエラーをスローし、制約のあるWorker環境はこれを致命的なエラーとして扱いました。その結果、スクリプト全体が終了し、インボックスは使用不能になり、AIエージェントも停止してしまいました。

バグの発見方法

SentryがWorkersからの未キャッチの例外をログに記録していました。クラッシュが発生した際、SentryはSQLiteがエラーを発生させた正確な行を記録しました。Sentryの「Seer AI」機能がスタックトレースを解析し、LIKEパターンの構築箇所を特定して、パターンの長さが原因である可能性を示唆しました。SQLiteのコンパイル時のドキュメントを素早く確認したところ、50バイトの制限が確認され、チームはGeminiを使用して制限を検証し、ユーザー入力の安全な最大長を算出しました。

ピンポイントな修正

解決には、既存の検索ルーチン内で行う3つの小さな変更が必要でした。

  • 入力される検索用語に48文字の厳格な上限を設ける。
  • % ワイルドカードを結合する前に、入力文字列をその長さに切り詰める。
  • クエリの残りの部分は変更せず、新しいライブラリを追加することなく検索精度を維持する。

この調整はクエリがSQLiteに到達する前に行われるため、最終的なパターンが50バイトのしきい値を超えることはなくなり、Workerがクラッシュすることもなくなりました。追加の依存関係も導入していないため、コードベースは軽量なまま維持されています。

なぜこれが重要なのか

エッジホストのデータベースは低レイテンシのユースケースにおいて魅力的ですが、オンプレミス版と同じ制約も引き継いでいます。ランタイムが未キャッチの例外を致命的なものとして扱う場合、不明瞭なコンパイル時の制限が本番環境を停止させるバグになり得ます。今回の場合、クラッシュによって長い件名を入力したすべてのユーザーに対してAI搭載メールアシスタントが機能しなくなりました。これは、ユーザーエクスペリエンスとサーバーレスプラットフォームの信頼性の約束に対する直接的な打撃です。

改善できた点

修正は単純なものですが、検証ステップの欠落を浮き彫りにしています。SQL文字列を構築する前にパターンの長さをチェックする入力サニタイズを行っていれば、本番環境ではなく開発段階でこの問題を発見できていたはずです。

次に注意すべきこと

エッジランタイムにSQLiteをデプロイする開発者は、パターンマッチングを含むすべてのクエリ構築、特にワイルドカードやエスケープ文字を追加するものについて監査を行うべきです。SentryはSQLiteが失敗した正確な行を捉えました。エッジコンピューティングが普及するにつれ、隠れたプラットフォームの制限がより頻繁に表面化するようになるため、ドキュメント化された制約に基づいて入力を検証する習慣が功を奏するでしょう。

教訓: SQLiteのLIKEパターンにおける50バイトの上限はCloudflare Workersをクラッシュさせる可能性がありますが、検索用語を48文字に切り詰めることで、余計な負荷をかけることなく問題を解消できます。これは、小さな検証ステップがエッジサービスの安定性を維持できることの証明です。