ServiceNowの入力チェックはClient ScriptとBusiness Ruleのどちらに書く? 実機の件数と判断基準
入力チェックをフォーム側とサーバ側のどちらに書くか、迷ったことはないでしょうか。同じ「必須にする」「値を検証する」という依頼でも、Client Scriptだけで実装すると、REST APIやImport Setからの更新はその検証を通らずに保存されます。Zurich PDIでBusiness Rule 5,719件・Client Script 2,585件の設定を数え、incidentのOOTB実装から実例を1つ確認しました。
検証環境:Zurich PDI / OOTB / 2026-08-08 確認
結論:判断基準は3つ、迷ったら「保存を止めたいか」で決める
先に全体像です。
保存そのものを止めたいなら、経路を問わずBusiness Ruleです。REST API・Import Set・バックグラウンドスクリプトからの更新もBusiness Ruleは実行しますが、Client Scriptはブラウザでフォームを操作したときにしか動きません。
入力中に見た目をすぐ変えたいなら(警告表示・自動計算・onChangeでの値の補完)Client Scriptの担当です。表示・必須・読み取り専用の切り替えだけで足りるなら、スクリプトを書かないUI Policyが3つ目の選択肢になります。
データの整合性を最後まで守れるのはサーバ側だけです。incidentのOOTB実装を確認したところ、クローズ時に必須にしている項目のチェックがClient Script側にしか実装されていない例が見つかりました。

上の図が判断の流れです。最初に聞く問いは「UI以外の経路からの更新も止めたいか」の1つだけです。ここで止めたいと答えたら選択肢はBusiness Rule一択で、それ以外は表示の切り替えだけで足りるかどうかでUI PolicyかClient Scriptに分かれます。図の色は役割の違いを表しています。濃紺は出発点、橙は分岐点の質問です。緑はクライアント側で完結する仕組み、赤はサーバ側でなければ守れない仕組みを示します。灰色はClient Scriptが届かない経路です。

全体の件数は上の表のとおりです。Business Ruleが5,719件、Client Scriptが2,585件で、Business Ruleの方が2倍以上多く登録されています。参考として3つ目の選択肢であるUI Policyも2,909件ありました。
Business Ruleは5,719件、6割がbeforeに集中していた
Business Rule(sys_script)は、レコードの登録・更新・削除・照会をきっかけにサーバ側で動くスクリプトです。件数は5,719件でした。

whenで内訳を見ると、保存前に動くbeforeが3,441件で全体の6割を占めています。保存後に動くafterは1,456件、フォーム表示前に動くbefore_displayは601件、非同期のasync系は212件でした。入力チェックの多くが「保存する前に止める、または直す」という使い方に寄っていることが件数からも読み取れます。
orderの設定も確認しました。5,719件のうち4,840件、割合にして84.6%が既定値の100のままです。order=100より小さい値を設定しているものが265件、大きい値を設定しているものが614件で、実行順を細かく調整しているBusiness Ruleは全体の15%程度にとどまります。
保存を止める設定はチェックボックスだけではない
Business Ruleにはabort_actionという保存を中断するチェックボックスがあります。trueになっているものを数えると157件でした。

157件という数字を見て、保存を中断するBusiness Ruleはこれだけかと思いましたが、そうとは限りません。スクリプトの中で条件を満たしたときだけcurrent.setAbortAction(true)を動的に呼ぶ書き方もあり、この場合フォーム上のabort_actionチェックボックス自体はfalseのままです。件数を数えるだけでは、保存を止める設定の実数を取りこぼします。実例は後述します。
条件式についても数えました。対象を絞るfilter_conditionを設定しているものが1,856件(32.5%)、スクリプトで条件を書く詳細条件(condition欄)を使っているものが1,550件(27.1%)です。無条件に動くBusiness Ruleの方がまだ多い一方で、3割前後は対象を絞ってから動く設計になっていました。
Client Scriptは2,585件、onChangeが半数を超える
Client Script(sys_script_client)はブラウザ側で動くJavaScriptで、フォームを開いたとき・項目が変わったとき・保存ボタンを押したときに実行されます。件数は2,585件でした。

typeの内訳はonChangeが1,350件で全体の過半数を占め、onLoadが1,004件、onSubmitが199件、セルの直接編集を捉えるonCellEditが31件です。項目が変わった瞬間に反応する使い方が、Client Scriptの主な役割になっています。
isolate_script(strict mode)の設定も確認しました。trueが1,497件(57.9%)で最多ですが、falseを明示しているものが347件(13.4%)、欄自体が空欄のものが741件(28.7%)ありました。空欄は既定値のfalseとして扱われるため、実質的にはfalse相当が半数近くを占めます。DOMへの直接アクセスやjQueryを使う古い書き方のClient Scriptが、今も一定数残っていることがうかがえます。
対象範囲を広げるapplies_extended(拡張テーブルにも継承)はtrueが211件(8.2%)にとどまり、ほとんどのClient Scriptは登録したテーブル単体を対象にしています。ui_typeはDesktop限定が1,339件(51.8%)、Desktop・Mobile両方を意味するAllが1,092件(42.2%)でした。Mobile・Service Portal限定はわずか31件(1.2%)にとどまります。
incidentだけに絞ると、Business Rule 39本・Client Script 25本
全体の傾向がテーブル1つでも当てはまるかを確認するため、incidentに絞って数え直しました。


incidentのBusiness Ruleは39本、Client Scriptは25本でした。全体では2倍以上の差があったBusiness RuleとClient Scriptの比率が、incidentでは39対25とやや縮まっています。1テーブルあたりで見ると、画面側の細かい出し分けにもそれなりの本数を割いていることが分かります。

内訳はBusiness Ruleがbefore 24・after 11・before_display 3・async 1でした。Client Scriptはonchange 12・onLoad 10・onSubmit 3・onCellEdit 0という内訳です。全体の傾向と同じく、Business Ruleはbeforeに、Client Scriptはonchangeに偏っています。
OOTBの実例:クローズ時の必須項目はどちらに実装されているか
incidentをCloseまたはResolveするとき、Close notesとClose codeが必須になる場面を見たことがあるはずです。この必須化がどちらの仕組みで実装されているかを実機で確認しました。

見つかったのは(BP) Close Mandatory on Close or Resolveという名前のClient Scriptです。typeはonSubmitで、g_form.getActionName()がclose_incidentかresolve_incidentのときだけ動きます。スクリプトの中ではg_form.setMandatory('close_notes', true)とg_form.setMandatory('close_code', true)で必須化したうえで、空欄ならreturn falseでフォームの送信そのものを止めています。
このBusiness Rule版に相当する処理を探しましたが、見つかりませんでした。sys_dictionaryでincidentのclose_codeを確認すると、mandatory欄はfalseのままです。collection=incidentのBusiness Ruleをscriptの中身でclose_notes検索にかけると、値が空なら補完する処理(Caller Closeなど)は見つかりました。ただし、空だったら保存を止める処理はありません。この検証の範囲では、クローズ時の必須化はonSubmitのClient Script 1本だけに依存しています。抜け道は、実装の中に残っていました。フォームのSubmitボタンを経由しない更新であれば、close_notesが空のままレコードが保存される可能性が実装上は残っている状態です。
もう1つ、サーバ側だけで実装できる中断の実例も見つかりました。

Check if Known error article requiredという名前のBusiness Ruleで、Resolution codeがKnown errorに変わり、かつStateがResolvedに変わるときに動きます。スクリプトの中では、関連するKnowledge記事が1件も見つからなければcurrent.setAbortAction(true)を呼び、gs.addErrorMessageでエラーメッセージを出しています。前述のとおり、このBusiness Ruleのフォーム上のabort_actionチェックボックス自体はfalseのままです。中断するかどうかを条件によって動的に決める書き方で、こうした処理はサーバ側でしか組めません。
実機で気づいたこと
Client Scriptのisolate_scriptを数えたとき、trueが最多という結果は想定どおりでしたが、空欄が741件(28.7%)も残っていた点は意外でした。予想は外れました。ServiceNowの案内文では、新しいClient Scriptは既定でstrict modeになると説明されています。空欄のまま残っている件数の多さは、この項目が追加される前から存在するClient Scriptが今も現役で動いていることを示しています。
Business Ruleのabort_actionも、数える前と後で見え方が変わりました。チェックボックスがtrueのものは157件だけですが、Check if Known error article requiredのように、チェックボックスはfalseのままスクリプト内で条件付きにsetAbortActionを呼ぶ書き方が実際に存在します。保存を止めるBusiness Ruleを数えたいとき、abort_action=trueという条件だけでは足りません。スクリプト本文まで見る必要があります。
incidentのクローズ必須チェックがClient Script側にしか実装されていなかった点も、実務では見落としやすい部分だと感じました。フォームを使う限りは必須チェックが効くため、画面から操作している人には問題が起きません。見えている挙動と、実際にサーバ側で守られている範囲が一致するとは限らない、という前提を持っておいたほうが安全です。
実務での使い分け:依頼を受けたときにどこを見るか

依頼を受けたときに自分がまず確認するのは、次の2点です。
その処理は、画面を経由しない更新(REST API・Import Set・他のスクリプトからの呼び出し)でも守られるべきか
守られるべきなら、Business Ruleのbeforeに書き、abort_actionかsetAbortActionで保存を止める
「入力中に警告を出したい」「関連項目を自動で埋めたい」という依頼であれば、多くの場合はClient Scriptで十分です。反対に「この状態では絶対に保存させたくない」「金額の上限を超えたレコードを作らせたくない」という依頼であれば、Client Scriptだけで応えると、フォーム以外の経路からの登録・更新を見逃します。
条件と結果の組み合わせだけで足りる表示制御は、UI Policyから検討したほうがコードを書かずに済みます。今回の実機ではUI Policyが2,909件登録されていて、Client Scriptの2,585件よりわずかに多い数字でした。スクリプトを書く前に、UI Policyだけで表現できないかを確認する習慣は、保守のしやすさにつながります。
つまずきやすい点
Client Scriptのonload・onChangeで必須項目を設定しても、その設定はブラウザのメモリ上にしか存在しません。ページを離れて別の経路からレコードを更新すれば、その必須設定は最初から働きません。画面の外は無防備です。今回確認したincidentのクローズ必須チェックも、この構造をそのまま体現した実例でした。
もう1つのつまずきどころは、Business Ruleのwhenを間違えることです。値を補正したいのにafterを選ぶと、すでに保存された後のレコードに対して2回目の更新をかけることになり、after同士が連鎖して余分な処理が走る原因になります。値を保存前に直したいならbefore、保存が終わった後に他のレコードへ連携したいならafterという役割の違いを、着手前に確認しておくとやり直しが減ります。
よくある質問
Q1. UI PolicyとClient Scriptはどちらを優先すべきですか
表示・非表示・必須・読み取り専用の切り替えだけで足りるなら、UI Policyを優先します。条件と結果を登録するだけで動くため、後から見た人がスクリプトを読まなくても設定内容を追えます。計算式や外部データの参照が必要になった時点で、Client Scriptへの切り替えを検討する形です。
Q2. Client ScriptでもREST経由の更新を止められますか
止められません。Client Scriptはブラウザでフォームを操作したときに実行される仕組みです。REST APIやImport Set、バックグラウンドスクリプトからの更新はブラウザのフォームを経由しないため、Client Scriptそのものが実行されません。経路を問わず保存を止めたい処理は、Business Rule側に置く必要があります。
Q3. Business Ruleのbeforeとafterはどちらから検討すればいいですか
値を検証したい、保存前に値を直したいという依頼であればbeforeから検討します。afterは保存が確定した後に動くため、値を書き換えても同じレコードに対してもう一度保存処理が走ります。他のレコードへの連携や通知はafter、対象レコード自身の値を直す処理はbeforeという役割分担が基本形です。
Q4. abort_actionチェックボックスを見れば、保存を止めるBusiness Ruleを全部洗い出せますか
洗い出せません。今回の実機でもチェックボックスがtrueのものは157件でしたが、スクリプト内で条件付きにcurrent.setAbortAction(true)を呼ぶ書き方のBusiness Ruleが別に存在しました。チェックボックスの値だけでなく、スクリプト本文の中身まで確認する必要があります。
Q5. Client Scriptで書いた入力チェックを、後からBusiness Ruleに移すべき場面はありますか
「フォームを経由しない更新でもその条件を守りたい」と気づいた時点が移すタイミングです。今回のincidentのクローズ必須チェックのように、画面からの操作だけを想定して作られたClient Scriptがあります。後からIntegration Hub連携やデータ移行のためにREST APIを使い始めた瞬間、その判定は守られなくなります。保存条件として重要度が上がったタイミングで、同じ判定をBusiness Rule側に複製する形が現実的です。
まとめ
入力チェックをどちらに書くかは、保存を止めたいかどうかで決まります。基準は1つです。経路を問わず守りたいならBusiness Rule、入力中の即時フィードバックで足りるならClient Script、条件と結果の組み合わせだけならUI Policyです。
件数はBusiness Ruleが5,719件、Client Scriptが2,585件、UI Policyが2,909件でした。Business Ruleのwhenは6割がbefore、Client Scriptのtypeは過半数がonChangeという結果です。incidentに絞ってもBusiness Rule 39本・Client Script 25本と、全体と同じ傾向が見られました。
abort_actionチェックボックスが157件、スクリプト内で動的に保存を止める書き方が別に存在することが分かりました。incidentのクローズ必須チェックがClient Script側にしか実装されていなかったことも、件数だけでは見えてこなかった実装の実態です。フォームの外からレコードが更新される機会があるなら、今回の実例と同じ抜け道が自分の担当システムにも残っていないか、一度確認しておく価値があります。
用語
Business Rule(sys_script) … レコードの登録・更新・削除・照会をきっかけにサーバ側で動くスクリプト。when(before/after/async/display)で実行タイミングが決まる
Client Script(sys_script_client) … ブラウザ側で動くJavaScript。onLoad・onChange・onSubmit・onCellEditのいずれかで実行される
UI Policy(sys_ui_policy) … 条件によって項目の表示・必須・読み取り専用を切り替える、スクリプト不要の設定
abort_action / setAbortAction … Business Ruleで保存処理そのものを中断する仕組み。フォームのチェックボックスとスクリプト内呼び出しの2通りがある
isolate_script … Client ScriptをDOM直接アクセス禁止のstrict modeで動かす設定
実機で調べるときに開いたURL
/sys_script_list.do?sysparm_query=GROUPBYwhen … Business Ruleをwhenでグループ化した一覧
/sys_script_client_list.do?sysparm_query=GROUPBYtype … Client Scriptをtypeでグループ化した一覧
/sys_script_list.do?sysparm_query=collection=incident^ORDERBYorder … incidentのBusiness Rule一覧
/sys_script_client_list.do?sysparm_query=table=incident … incidentのClient Script一覧
/sys_script_list.do?sysparm_query=abort_action=true … abort_actionがtrueのBusiness Rule一覧
参考リンク
さらに詳しく知りたい人へ
ServiceNowで処理を書くならどこ? Business Rule・Client Script・ACLの使い分けを実機の件数から考える — ACLやScript Includeまで含めた6つの仕組み全体の入口
Client ScriptとUI Policyの違い(フォーム挙動) — 画面側2つの仕組みをさらに掘り下げた実例
Business Ruleはどの順番で動くか:incidentの39本を並べて確かめる — 今回のincident 39本を、orderの実行順で並べ直した続編
検証環境と未検証範囲
件数はZurich PDI(OOTB)で2026-08-08に確認したものです。一覧画面の件数表示とスクリプト本文を突き合わせて数えており、推定やサンプリングではありません。本番環境やカスタマイズ済みの環境では数値が異なります。
REST APIで実際にclose_notesを空のまま更新できるかどうかの実行テストは、今回は行っていません。Client ScriptとBusiness Ruleの構造上の違いから導ける事実として記載していますが、書き込みを伴う検証は範囲外です。Business Rule・Client Scriptの実行速度や、スコープアプリ内のカスタムスクリプトの個別内容も扱っていません。