スキーマの可変性 — 作成後に変えられるものと変えられないもの
作成後に select カラムのオプションが実質的に閉じてしまう理由と、その狭い例外
概要
「スキーマは作成時に固定され、API からは変更できない」という一括りの主張は、真実に近いが厳密には正しくない。この機微は、外部のステータスフィールドを写す select カラムを設計する人にとって重要だ:作成時にオプションを多めに用意しておくコストは安いが、あとから 1 つ増やすコストは安くない。
slackLists.update が受け取るのは 4 フィールドだけ
slackLists.update は既存リストのトップレベルの形を変更する唯一のメソッドであり、受け取るのはちょうど id、name、description_blocks、todo_mode だけだ。12 個の slackLists.* メソッドのどれも、カラムの型・名前・オプション集合を直接触ることはない。
オプションを追加・改名・削除するドキュメント化された経路は存在しない
書き込みはカラムの既存の定義に対して検証される:options.choices[] に存在しないオプション値を送ると invalid_option_id で失敗する(items.create 版の同じエラーは "Option ID provided does not match column definition" と読める)。セルの形 {column_id, select: string[]} には新しいオプションのラベルや色を運ぶ構造的な余地がない — 書き込み契約のどこにもオプションを 定義する 場所はなく、すでに存在するものを 選ぶ 場所しかない。
エラーレジストリに何が欠けているかが、これを補強する:ドキュメント化されたおよそ 50 個のリスト系エラーのどこにも option_id_to_create は存在しない一方で、行とカラムの作成に対応するもの(row_id_to_create、column_id_to_create)は両方とも存在する。この非対称性は、オプション集合が API に対して意図的に閉じられているという構造的な証拠だ — 行とカラムの作成には逃げ道が与えられたが、オプションの作成には与えられなかった。
唯一の本物の例外:todo_mode
todo_mode: true を指定した slackLists.update は、メソッド自身の使い方の散文によれば、既存の リストにタスク管理用のカラム — Completed(todo_completed)、Assignee(todo_assignee)、Due date(todo_due_date)— を追加させる。これは API サーフェス全体で唯一の、ドキュメント化された作成後のスキーマ追加だ。逆に言えば、todo_mode: false でリストを作った場合、この 3 カラムについては確定とみなして差し支えない。
column_id_to_create — 機能ではなく、ドキュメント化されていない裂け目
column_id_to_create の名が挙がるのは column_id_not_provided のエラー文字列("The column_id or column_id_to_create field must be provided")の中だけだ。どのメソッドのドキュメントページにも引数の定義はなく、動く例もなく、公式 3 SDK の型のいずれにも存在しない。
ドキュメント化されていない — 依存しないこと
column_id_to_create には実世界での使用例の確証がゼロであり(コード検索で見つかるのは同じエラー文字列のミラーばかりで、実際の呼び出し箇所は一度も出てこない)、実際の API による検証もどちらの方向にも存在しない。サポートされたカラム作成の経路ではなく、未実証のバリデータの残滓として扱うこと。本当に新しいカラムが必要なら、本番でこのフィールドを探るのではなく、後述の公認された copy_from_list_id による作り直しの回避策を使うこと。
人間は UI からスキーマを編集できる
ここまでの記述はすべて API サーフェスについてのものだ。編集アクセスを持つ人間は、Slack の UI からいつでも直接オプションの追加・削除やラベルの変更ができる — スキーマの不変性は「API に対して閉じている」のであって、「完全に閉じている」わけではない。
このことには運用上の直接的な帰結が 1 つある:キャッシュした value → label のマップは運用の途中で陳腐化しうる。削除されたオプションは、それまで成功していた書き込みに対して invalid_option_id を返し始める。一方でラベルの変更は安全だ、書き込みが指定するのは label ではなく value だからだ。予期しない invalid_option_id に遭遇したら、スキーマが変わらないことを前提としたハードコードの定数を信じるのではなく、items.info 経由で list_metadata.schema を読み直すこと。
公認の回避策:copy_from_list_id による作り直し
「オプションをもう 1 つ増やしたい」に対するドキュメント化された API 経路は 新しいリスト だ:copy_from_list_id と include_copied_list_records を指定した slackLists.create を使う。同じ呼び出しで copy_from_list_id と schema の両方を渡すことはできず — その組み合わせは invalid_copy_and_schema_args で失敗する — したがって新しいリストはコピー元のスキーマの完全な複製として始まり、オプションの追加はそのあと UI から手作業でやるか、手で編集したコピー元リストからもう一度作り直すことになる。いずれにせよ、これは真新しい list_id とすべてのカラムの新しい column_id を発行するので、あらためて永続化し直す必要がある。
計算列は書き込めない
created_by、last_edited_by、created_time、last_edited_time は Slack が計算するカラムであり、スキーマの状態にかかわらず書き込みを試みると常に uneditable_column を返す。
設計時に織り込むべき上限
slackLists.create のドキュメント化された制約より:
| 上限 | 値 |
|---|---|
| select カラムあたりのオプション数 | 100 |
| セルあたりの選択値の数 | 50 |
| 使用できるチップの色 | indigo、blue、cyan、pink、yellow、green、gray、red、purple、orange、brown |
実務上の帰結:作成時に多めに用意しておく
既存カラムのオプション集合を編集する API 経路が存在しない以上、実際に機能するパターンは リスト作成時にステータスのオプションを多めに用意しておく ことだ — 100 オプションの上限までの範囲で、まだ使わない予備のスラッグを焼き込んでおく。あとから本当に新しいオプションが必要になったら、人間が UI から手作業でリストを編集するか、上記の copy_from_list_id の回避策でリストを作り直すかのどちらかになる。
関連
この閉じたオプション集合が制約している書き込みの契約はリストアイテムへの書き込みと select カラムを参照。invalid_option_id をはじめ、このページの制約が生むエラーについてはエラーリファレンスを参照。