ServiceNowのクライアントスクリプトが動かない典型原因と切り分け手順

ServiceNow

はじめに:なぜ「動かない」は起きるのか

ServiceNowの学習で、わりと早い段階でぶつかるのが「クライアントスクリプトが動かない」問題です。書いたはずなのに反応がない。保存してもフォームが変わらない。onChangeが発火しない。焦りますよね。

ここで大事なのは、“コードの間違い”より前に、設定や適用範囲のズレが原因になりやすいということです。クライアントスクリプトは、サーバ側(Business Ruleなど)と違って、次の要素が噛み合って初めて動きます。

  • どの画面(どのUI)で動かすのか
  • どのテーブル/どのフィールド/どのビューが対象なのか
  • どのタイミング(onLoad / onChange / onSubmit など)で動かすのか
  • 競合する設定(UIポリシー、別のスクリプト、カタログ設定)がないか

この「ズレ」を体系的に潰せるようになると、試験対策としても実務としても強いです。暗記ではなく、“動く条件”を構造で理解できるからです。

この記事では、初学者がよく踏む典型パターンを、切り分け手順と具体例つきで整理します。


本番形式で慣れるのが合格への近道。UdemyのServiceNow模擬問題集を人気順で一覧比較できます👇

典型原因その1:種類・対象・条件のズレ

「動かない」とき、最初に見るべきはコードよりレコード設定です。クライアントスクリプトは“正しい場所に置かれていない”と、何も起きません。

テーブルが違う

Incidentで作ったつもりが、実は拡張テーブル側に置いていた、あるいは逆…というパターンがあります。
フォーム上で見ているレコードがどのテーブルかは、画面上の情報や辞書、URLなどでも確認できます。

  • 今開いているフォームがどのテーブルかをまず確定
  • 継承(extends)がある場合、どの階層に置くべきかを考える
    • 親(例:task)に置けば広く効く
    • 子(例:incident)に置けば限定して効く

「どこに置くと、どこまで影響するか」はCSA学習でも混乱しやすいポイントです。

クライアントスクリプトの種類が違う

同じ“クライアントスクリプト”でも、レコードフォーム用サービスカタログ用は別物です。

  • Record Client Script:通常のテーブルフォーム(incidentなど)
  • Catalog Client Script:カタログアイテム、レコードプロデューサ、変数(Variables)周り

カタログ変数で動かしたいのに、レコード側に書いても当然動きません。逆も同様です。
「今触っているのはフォームなのか、カタログなのか」を最初に言語化すると迷子になりにくいです。

UI Type / View / Applies to のズレ

環境によって表示するビューが違うと、スクリプトの適用ビューが合わず動かないことがあります。
また、特定UIだけ対象にしている設定(UI Typeなど)も見落としがちです。

チェック観点の例:

  • Applies to(対象):All / Desktop / Mobile などの指定が意図通りか
  • View:スクリプトが特定ビューに限定されていないか(または逆に限定したいのにAllになっていないか)
  • Active:基本ですが、地味にあります

条件(Condition)が常に false

「条件付きで動かす」つもりが、条件が厳しすぎて一度もtrueになっていないケースです。
慣れないうちは、まず条件を外して動作確認→条件を戻す、が安全です。

コツ:動作確認用に一時的なメッセージを出す

  • g_form.addInfoMessage('Client Script fired');
    これだけでも「発火してる/してない」が一瞬で分かります。

典型原因その2:実行タイミングとイベントの誤解

クライアントスクリプトは「いつ動くか」を間違えると、書いていても無音になります。

onChangeが発火しない代表例:「ロード中」と「同じ値」

onChangeは基本的にユーザー操作で値が変わったときに発火します。よくある勘違いは次の2つです。

  • フォーム表示直後に動くと思っていた(→それはonLoad寄り)
  • 同じ値を再セットしている(値が変わっていないので発火しない)

さらに、onChangeには多くの場合 isLoading が渡されます。フォームロード中に余計な処理をしないよう、よく次のように書きます。

  • ロード中はreturnする
  • 空値ならreturnする

これ自体は良いのですが、return条件が強すぎて、実質いつもreturnになっていることがあります。

例:空値チェックが厳しく、ユーザーが選ぶ前に抜ける
例:ロード判定の扱いが雑で、ユーザー操作でも抜ける

まずはチェックを最小限にして、発火を確認してから守りを固めるのが近道です。

onLoadに書いたのに期待通りにならない:「値がまだない」

onLoadはフォームが読み込まれたタイミングですが、関連データや参照情報が完全に揃う前のこともあります。
参照先から値を取る、グライドAJAXで何か引く、といった処理は、順番の影響を受けやすいです。

この場合は、

  • そもそもonLoadでやる必要があるか
  • UIポリシーやデフォルト値設定で代替できないか
  • 非同期処理(コールバック)の書き方が正しいか
    を考えます。

onSubmitが「保存時」だと思っていた

onSubmitは保存ボタン等で送信される直前に動きますが、UIの動きや必須チェック、別の仕組みとの組み合わせで「思ったタイミングと違う」ことが起こります。

例えば、onSubmitで値をセットしても、別のバリデーションで止まる、別スクリプトで上書きされる、などです。
「保存前に必須チェックしたい」のか「保存直前に値を整形したい」のか、目的を分けると設計しやすいです。


典型原因その3:UI体験の違いと競合

「単体では正しいのに効かない」ときは、競合を疑います。

UIポリシーが上書きしている

初心者が混乱しやすいのがこれです。たとえば、

  • クライアントスクリプトで g_form.setReadOnly(false) にした
  • でもUIポリシーが同じフィールドをRead-onlyにしている
  • 結果:見た目は変わらない(または一瞬変わって戻る)

UIポリシーはノーコードで強力ですが、同じフィールドに対して複数の制御があると、最終的にどれが勝っているかを追いづらくなります。
まずは、対象フィールドに関係するUIポリシーを洗い出して、当たりを付けましょう。

同じイベントに複数スクリプトがいる

onChangeが複数ある、UI ScriptやUI Actionが絡む、クライアント側ライブラリが入っている、など。
このとき起きるのが「後から動いた処理が上書きする」問題です。

対策としては、

  • 一時的に対象スクリプト以外を無効化して比較する
  • 何が最後に値を変えたかをログで追う(console.logなど)
  • 役割を分ける(値セット担当と表示制御担当を混ぜない)

Workspace / UIの違いで動作が変わる

環境によっては、同じフォームでも体験が異なります。いわゆる“どのUIで開いているか”です。
この話は深掘りすると長いですが、初学者の段階ではまず、

  • 自分が今見ている画面は、想定していたUIと同じか
  • 「そのUIで」クライアントスクリプトが想定通り発火する設定になっているか

を確認するだけでも、ハマりが減ります。


典型原因その4:デバッグ手順と“再現できない”問題の潰し方

「動かない」を短時間で切り分けるには、順番が大事です。おすすめの流れはこれです。

まず発火確認:最小の目印を入れる

最初にやるのは、コードの正しさ以前に「発火しているか」を確定することです。

  • g_form.addInfoMessage('fired');
  • 可能なら console.log('fired');(ブラウザ開発者ツール)

これで、発火していない=設定/対象/条件/UIの問題
発火している=コードの中身/競合/タイミングの問題
と切り分けができます。

変数・フィールド名の勘違いを疑う

g_form系で多いのが「表示名」と「内部名」の取り違えです。

  • 画面のラベル:例「Caller」
  • 内部名:例 caller_id

g_form.getValue('Caller') のようにラベルを入れてしまうと動きません。
辞書(Dictionary)で内部名を確認する癖をつけると、ここは安定します。

キャッシュ・反映遅延を疑う

変更したのに古い動作が残るときは、ブラウザキャッシュや反映のタイムラグもありえます。
ただ、むやみに疑うと時間が溶けるので、まずは発火確認→設定確認→競合確認の後で「最後の手段」くらいの位置づけが良いです。

権限・ACLの影響で“見えてない/編集できない”ケース

「スクリプトは動いているのに値が入らない」場合、ユーザー権限側の制約が絡むことがあります。
たとえば、ユーザーが編集できないフィールドに setValue しようとしても、結果が見た目に反映されない(または保存されない)ことがあります。

ここは“クライアントスクリプトが悪い”と決めつけず、フィールドがそもそも編集可能かを確認すると早いです。


典型原因その5:現場で効くパターン別処方箋

ここからは、よくある症状→原因→対処をセットで整理します。初学者が「次に何を見ればいいか」が分かる形にしています。

ケース:onChangeがまったく動かない

ありがちな原因

  • 対象フィールドが違う(内部名ミス、別フィールドを見ている)
  • 条件がfalse(Condition、Applies to、View)
  • CatalogとRecordを取り違えている

対処

  • 対象フィールドの内部名を辞書で確認
  • 条件を一旦外し、addInfoMessage で発火確認
  • カタログならCatalog Client Script/変数イベント側に置き直す

ケース:一瞬だけ動いて元に戻る

ありがちな原因

  • UIポリシーや別スクリプトが上書き
  • 2つ以上のonChangeが同じフィールドを触っている

対処

  • 対象フィールドに関わるUIポリシーを洗い出す
  • いったん片方を無効化して挙動比較
  • “表示制御”と“値セット”の役割を分けて整理する

ケース:g_form.setValueしたのに値が変わらない

ありがちな原因

  • 指定したフィールド名が間違い
  • フィールドが読み取り専用(UIポリシー含む)
  • 参照フィールドで、入れる値の形式を誤解している(sys_idが必要など)

対処

  • 内部名の再確認
  • 読み取り専用の原因を(UIポリシー/権限/フォーム設定)で切り分け
  • 参照フィールドは「表示値」と「実体(sys_id)」の違いを意識して設計する

ケース:特定ユーザーだけ動かない/環境で再現しない

ありがちな原因

  • ロールやACLで編集可否が違う
  • ビューやフォームレイアウトが違う(見ている画面が別)
  • UI体験が違う(開き方が違う)

対処

  • そのユーザーで「どのビュー」「どのUI」で開いているかを合わせる
  • フィールド権限(編集可否)を確認する
  • “同じ条件で再現する”を最優先にして、再現できてから原因を掘る

まとめ:原因は「ズレ」「順番」「競合」。体系で覚えると強い

クライアントスクリプトが動かないとき、原因は大きくこの3つに収束します。

  • ズレ:テーブル、種類(カタログ/レコード)、対象フィールド、ビュー、条件
  • 順番:onLoad/onChange/onSubmitのタイミング、ロード中、非同期の扱い
  • 競合:UIポリシー、他スクリプト、別UIでの挙動差

この3分類で考えるだけで、「何を調べるべきか」が整理され、闇雲に試行錯誤する時間が減ります。CSA学習としても、単なる暗記より“仕組みの前提”が積み上がるので、他の領域(UIポリシー、ACL、フォーム設計)にも理解が波及します。

もし「原因の切り分けは分かったけど、そもそもクライアント側の基本(g_form、イベント、カタログとの違い)を一気に整理したい」と感じたら、体系的にまとまった教材を1つだけ軸にするのも手です。Udemyには、フォーム制御やクライアント側の基礎を章立てで学べる講座もあるので、「自分の理解が抜けやすい部分を埋める」目的で使うと相性が良いと思います。

本番形式で慣れるのが合格への近道。UdemyのServiceNow模擬問題集を人気順で一覧比較できます👇

タイトルとURLをコピーしました