You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: plugins/power-pages/skills/add-server-logic/SKILL.md
+61Lines changed: 61 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -432,6 +432,26 @@ Repeat this step for each approved server logic item. Create or update `<PROJECT
432
432
6. **No browser APIs**: No `fetch`, `XMLHttpRequest`, `setTimeout`, `setInterval`, `console.log`, or DOM APIs.
433
433
7. **Async when needed**: Mark functions as `async` only when they use `await` (HttpClient calls). Dataverse connector methods (`Server.Connector.Dataverse.*`) are **synchronous** — do NOT use `async`/`await` with them.
434
434
435
+
#### Prohibited Script Patterns
436
+
437
+
The Power Pages server-side script validator rejects scripts containing certain patterns at runtime. Violations surface as `RTSL01: Script validation failed: prohibited pattern found - Pattern: <regex>` in diagnostics, and the function silently falls through without executing user code.
438
+
439
+
| Pattern | Regex | Caveat |
440
+
|---------|-------|--------|
441
+
| JavaScript `with` statement | `with\s*\(` | The regex matches the substring `with(` **anywhere** in the file — including inside string literals and inside other identifiers. OData filter functions like `startswith(`, `endswith(`, and `groupwith(` will trip it because they end with `with(`. |
442
+
443
+
**Workaround for OData functions** — split the literal so `with(` is not contiguous in source:
444
+
445
+
```javascript
446
+
// ❌ Triggers validator: "startswith(" contains the substring "with("
447
+
var query = "$filter=startswith(name,'INV-')";
448
+
449
+
// ✅ Split the literal — server still receives "startswith(name,...)"
450
+
var query = "$filter=startswith" + "(name,'INV-')";
451
+
```
452
+
453
+
The same trick applies to `endswith(`, `groupwith(`, and any other identifier that ends with `with(`.
454
+
435
455
#### Code Template
436
456
437
457
```javascript
@@ -1112,6 +1132,7 @@ Provide testing instructions:
1112
1132
Use the frontend integration reference from Phase 9 for the exact calling pattern that matches the site's stack.
1113
1133
1114
1134
5. **Check diagnostics** — Server.Logger output can be viewed in Power Pages design studio diagnostics
1135
+
6. **If the endpoint returns an error or unexpected response** — see [Troubleshooting Server Logic Execution Errors](#troubleshooting-server-logic-execution-errors) for the Playwright + `X-Ms-UserTrace` debugging flow
1115
1136
1116
1137
**Output**: Code validated, API URL provided, test guidance given
1117
1138
@@ -1188,6 +1209,46 @@ After deployment (or if skipped), remind the user:
1188
1209
1189
1210
---
1190
1211
1212
+
## Troubleshooting Server Logic Execution Errors
1213
+
1214
+
When a deployed server logic endpoint returns an error or unexpected response, the underlying cause is usually hidden inside the `X-Ms-UserTrace` response header — a base64-encoded blob containing the runtime diagnostic logs. The Power Pages Edge browser extension shows the same data, but inspecting the response header is the fastest path when iterating against a live site.
1215
+
1216
+
Use this flow whenever a server logic call fails or returns a different response than expected:
1217
+
1218
+
### 1. Open the Live Site in a Browser via Playwright
1219
+
1220
+
Use the Playwright MCP tools to drive the site:
1221
+
1222
+
1. Navigate to the deployed site URL (the `websiteUrl` returned by `/activate-site` or shown in the Power Pages admin center).
1223
+
2. Ask the user to sign in if the endpoint requires authentication and wait for confirmation.
1224
+
3. Trigger the action that calls the failing server logic endpoint (click the button, submit the form, etc.) — or call the endpoint directly with `fetch()`.
1225
+
1226
+
### 2. Capture the Network Response
1227
+
1228
+
Use `mcp__plugin_power-pages_playwright__browser_network_requests` to list network activity, then locate the request to `/_api/serverlogics/<name>`. Note:
1229
+
1230
+
- The HTTP status code (e.g., 200, 400, 500)
1231
+
- The response body (often a generic error or empty payload when validation fails)
1232
+
- **Most importantly: the `X-Ms-UserTrace` response header** — this is where the actual diagnostic logs live
1233
+
1234
+
If `browser_network_requests` does not surface the response headers directly, fall back to `mcp__plugin_power-pages_playwright__browser_evaluate` and read the headers from a `fetch()` call:
0 commit comments