What's new
Added in the last 60 days, newest first. Follow along in your feed reader:Atom feed.
November 2026 41 new
- The hosted workbench restores your web parts on the next site you open in the same tab2026-11-14The hosted workbench keeps its canvas in sessionStorage per tenant origin, not per site; open another site's workbench in the same tab and your web part boots there — with that site's pageContext, so first-run…
- Service health — a cross-service outage is filed under "Microsoft 365 suite", not under SharePoint or Exchange2026-11-13Filtering serviceAnnouncement/issues by service dropped MO1550821 (12 Nov 2026, users unable to connect to multiple Microsoft 365 services) — its service was Microsoft 365 suite
- Moving a static CDN off GitHub Pages without breaking the apps that load from it2026-11-13Upload git blobs, not a Windows working tree (CRLF breaks SRI); allow the new CA in CAA; missing files must stay 404, not 403; Azure static website has no CORS and Front Door ignores the query string by default…
- Creating a team right after creating its Microsoft 365 group returns 404 — retry only the 404, and don't log the failure as success2026-11-13PUT /groups/{id}/team fails with 404 for minutes after POST /groups (replication); retry only 404, surface a real failure as a warning
- A "public mode" flag that disables the token check opens every endpoint in the Function App, not just the chat2026-11-13One Function App serves a signed-in SPFx app and an anonymous website chatbot; the website instance switches off the token check, and every other HTTP function in the same app (usage stats, storage read/write, file…
- /me/sendMail from an account without a mailbox can time out with 504 – and the Graph SDK retries it three more times2026-11-12No MailboxNotEnabled error, just a 504 after ~30 s; the SDK RetryHandler repeats the non-idempotent POST up to 3×, so the button hangs ~2 min and a late success can send duplicates; check assignedPlans for an enabled…
- A $filter literal encoded twice finds nothing — with a 2002026-11-12If a helper already percent-encodes the quoted literal, wrapping the whole $filter in encodeURIComponent encodes the value a second time (/ → %252F, @ → %2540); SharePoint then compares against the escaped text and…
- A folder created with folders/AddUsingPath in a generic list has no list item — breaking its permissions returns 4042026-11-12In a custom list (BaseTemplate 100) web/folders/AddUsingPath creates a 'naked' folder: ListItemAllFields is odata.null (@odata.null under SPFx's OData v4) and breakroleinheritance is 404. Create list folders with…
- Locking down a no-script site from code: web NoCrawl is denied even to a site collection admin, and turning off access requests returns 200 and changes nothing2026-11-12On a modern site with custom scripts disabled, NoCrawl on the WEB returns 403 via REST and CSOM even for a site collection admin, and SetUseAccessRequestDefaultAndUpdate(false) returns 200 without effect; both work…
- Search REST returns 500 "unknown error" and 429 "low resources" for minutes at a time — retry the read, don't fix the query2026-11-12SharePoint Search REST can fail for a few minutes with HTTP 500 SearchServiceException (no Retry-After) and HTTP 429 low-resources errors; the same query succeeds seconds later, so retry reads briefly with a fixed…
- An ECDSA signature made in Node fails crypto.subtle.verify in the browser — Node defaults to DER, WebCrypto expects raw r||s2026-11-12crypto.sign in Node returns a DER-encoded ECDSA signature (69–72 bytes); WebCrypto verify in an SPFx bundle expects IEEE P1363 (64 bytes for P-256) and just returns false. Sign with dsaEncoding ieee-p1363, check the…
- An SPFx web part that calls an intranet API makes Chrome and Edge ask every user for local network access2026-11-12A *.sharepoint.com page fetching a host that resolves to a private IP is a local network request – Chrome (from 142) and Edge prompt every user and a refusal is a bare Failed to fetch; pre-allow the SharePoint origin…
- Two "Uncaught (in promise)" from sp-pages-assembly on a modern page are SharePoint's own, not your web part2026-11-11On SharePoint Online modern pages the console can show two "Uncaught (in promise)" exceptions with reason undefined and a stack only inside sp-pages-assembly, on every load and on SPA navigation – they also appear on a…
- Retrying a write without the "new" columns on any 400 silently loses data — drop only the column the error names2026-11-11When one new column is missing, a group-wide retry drops the ones that exist too; drop only the fields the error names as not existing, loop, and tell the user what was left out
- Manifest SRI does not cover scripts your SPFx bundle loads itself (pdf.js, tesseract.js, workers)2026-11-11Pinning the loader in the .sppkg and giving every manifest path and webpack chunk an integrity hash still leaves a hole – third-party libraries your own code injects with a script tag, fetches for a worker or that a…
- Power Platform admin API returns nextLink on a regional host – a guard that only knows api.powerapps.com breaks paging for US tenants2026-11-11Admin listings page through unitedstates.api.powerapps.com (and other one-label regional hosts); a token guard that allows only the global host rejects page two, and you never see it on a small tenant – allow exactly…
- Manage Lists lets you read other people's items on a WriteSecurity 2 list, but not edit them — that takes Override List Behaviors2026-11-11On a list with item-level write security, the Edit role (Manage Lists) still gets 403 when it updates an item someone else created; only a role with Override List Behaviors (CancelCheckout, Low 0x100) gets through, so…
- Load an SPFx bundle's lazy chunk from the browser console — no clicking through the UI2026-11-11Push a fake chunk with a runtime callback into the bundle's webpackJsonp_ array to get its real __webpack_require__, then req.e(chunkId) loads the chunk exactly as the app would — for checking 404s, SRI integrity or…
- Renaming your SharePoint domain (contosoltd.sharepoint.com to contoso.sharepoint.com)2026-11-10Scheduling a tenant rename on a fresh tenant – checking the name is free, adding the matching .onmicrosoft.com domain the right way, the 24-hour scheduling floor (error -772), what -WhatIf and the status output look…
- List item versions come back newest-first and include the current one – the opposite of file versions2026-11-10items(id)/versions is DESCENDING and its first row is the current version (IsCurrentVersion: true) – the opposite of file /Versions; Created on a version is UTC WITHOUT the Z, so new Date() shifts it by the browser…
- A Teams message your app posts in the user's name doesn't notify that user — and "I can't see it" needs a read-back, not a guess2026-11-10Delegated ChatMessage.Send delivers (even to the self chat 48:notes), but Teams never alerts the sender; verify with GET + webUrl, notify from the app
- SPFx adds Subresource Integrity to a script when the manifest path is { path, integrity }2026-11-10A component manifest you pass to SPComponentLoader.loadComponent can carry an SRI hash per script resource as path { path, integrity }; SharePoint then emits script integrity crossorigin=anonymous and the browser…
- Console scripts on SharePoint hang because the ODSP service worker stalls every fetch2026-11-09A SharePoint page is controlled by the odspserviceworkerproxy.aspx service worker; when it gets stuck, every fetch from the page (even to another domain) never resolves while timers still run – a hard reload (Shift+F5)…
- A trailing-whitespace regex freezes the page when it parses AI output2026-11-08/\s+$/ and lazy (.+?)\s*$ are quadratic on a line with a long run of spaces that does not end the line; text from an AI model or a foreign document is untrusted input, so trim with trimEnd() and anchor captures on a…
- A textarea jumps after you change its text from code and restore the selection2026-11-08focus() scrolls the page to the element and, in Chromium, setSelectionRange scrolls the textarea to the end of the selection; restore the selection with focus({ preventScroll }) and put scrollTop back
- Two MERGEs to the same list item at once: the second one fails with 409 Save Conflict even with IF-MATCH: * – and a fire-and-forget write just disappears2026-11-08IF-MATCH: * only switches off the ETag check (412); SharePoint still refuses a second save of the same item while the first is in flight with 409 Save Conflict. Queue writes per item (list#id), retry 409 briefly, never…
- Restoring inheritance is a one-way door — snapshot the unique assignments first2026-11-07resetroleinheritance throws away every unique role assignment and SharePoint keeps no copy, so an "undo" is only possible if the code saved the assignments BEFORE the call; re-breaking with copyRoleAssignments=true…
- StorageMetrics lies two ways — all zeros, or plausible numbers from an older state2026-11-06zero = not calculated, but non-zero can be stale (261 files / 3.1 GB vs real 794 / 9.5 GB); trust it only when TotalFileCount exactly matches the files you counted
- accountEnabled eq false is not a list of leavers — blocked shared mailboxes are in it too2026-11-06blocked members ≠ former employees; tell shared mailboxes apart via the mailbox usage report's recipientType (needs real names) or mailboxSettings.userPurpose (per user)
- Purview audit query API — a query for a service you have no scope for still "succeeds" with 0 records2026-11-06With only AuditLogsQuery-SharePoint.Read.All, Exchange and Entra queries return 201 → succeeded → 0 records; an unfiltered query returns only SharePoint records
- Exchange Online Admin API (the REST behind EXO V3) cannot be called from the browser — no CORS, and SPFx tokens lack Exchange.Manage2026-11-06adminapi/beta/{tenant}/InvokeCommand fails with 'Failed to fetch' even with a fake token; read Exchange config with an admin-run script and import, or use Graph message trace and mailbox reports
- A shared stylesheet injected once per page keeps the version that rendered first — your CSS fix may not apply next to an older build2026-11-05A library that injects only if the id is missing lets whichever bundle renders first decide the CSS for every web part on the page, so a fixed rule in a newer bundle can silently lose to an older copy that rendered first
- Jest's 5-second default timeout fails render tests under load, and the timed-out test breaks the next one2026-11-05The first jsdom + React test of a suite pays for the cold module load; on a busy build machine it passes 5 s, Jest abandons it while its async render keeps running, and the following test fails with "button not found"…
- window.scrollTo does nothing in an SPFx web part on a modern page2026-11-05The page scrolls inside a canvas element, not the window; switching views in a single-page web part leaves the user mid-page. Find the real scrolling ancestor and reset that
- A user with Read on one page only is denied at the site root URL — link to the page, not the site2026-11-04When a principal has Read on a single page in Site Pages and only Limited Access on the site, opening the site URL ends on AccessDenied.aspx even though the page itself opens fine — so a link that falls back to the…
- Root site swap refuses hub sites, and any site Publishing ever touched2026-11-04Invoke-SPOSiteSwap rejects a source or target that is a hub site or associated with one, and rejects a source where the Publishing feature was ever activated — not just currently; unregistering a hub leaves children…
- Narrowing a principal to Read — "already reads" checked before stripping write leaves it with nothing2026-11-03Edit and Contribute contain the View bit, so a "does it already read?" check passes, Read is never added, and the step that removes the write binding then removes the only binding that carried read access — the…
- /_api/hubsites is trimmed per user — a lookup that walks the hubs finds your app for the page editor and not for the reader2026-11-03GET /_api/hubsites returned 2 hubs to an admin and 1 to an ordinary user who had Full Control on the missing hub's site, so client code that discovers something by walking the hub list works for the editor and silently…
- Scope SharePoint Search to hundreds or thousands of sites with RefinementFilters — and or() with one value returns nothing2026-11-03To restrict any Search query to an explicit list of site collections, POST to /_api/search/postquery with RefinementFilters SPSiteUrl:or(...) (tested with 3,000 URLs); a single value must use equals() because or() with…
- A file's time is not its item's time – a copy job carries the item time, and ListItemAllFields returns dates in the web's zone without "Z"2026-11-01TimeCreated/TimeLastModified of a file can differ from the item's Created/Modified by seconds or years; copy jobs carry the item time, so compare items – and read them from /items(id) (UTC), because ListItemAllFields…
- Copy jobs fed with file URIs: the folders you pre-create carry your account and today's date – and the TaxCatchAll warning is just image tags2026-11-01A CreateCopyJobs job that gets folder URIs carries folder metadata, a job fed with file URIs needs existing target folders, and folders created with AddUsingPath show the running account and the creation time until you…
October 2026 45 new
- Reading Teams channel messages needs a Teams license — a Global Admin without one gets 403 even as a team member2026-10-31Delegated GET /teams/{id}/channels/{id}/messages returns 403 'Failed to get license information for the user' for an unlicensed account even with ChannelMessage.Read.All consented and team membership; a licensed member…
- A copy job reports "finished" before the target shows every file – verify after the target settles, and read authors with $expand2026-10-31After CreateCopyJobs reports JobState 0, the target's /items can still miss hundreds of files for a while; re-read until two reads match, and compare authors via $expand on /items, not siteusers
- Which Entra ID roles are privileged? isPrivileged is beta-only, and a hand-written list gets it wrong2026-10-30Read isPrivileged live from beta roleDefinitions – v1.0 omits it and 400s on $select=isPrivileged; Exchange/SharePoint/Teams admins are not privileged
- Power Automate admin flows API returns UserImpersonationScopeMissing from SPFx – even after you approve the scope2026-10-30SharePoint's token for Microsoft Flow Service carries only Microsoft's preauthorized scopes, so an approved User grant never reaches the token and the tenant-wide flows list stays 401
- A generated PowerShell script that embeds file names in a here-string runs code under the admin who runs it2026-10-30Data that tenant users can name (file paths, titles) breaks every textual PowerShell literal – expandable here-strings run $(…), ; splits CSV rows, '@ ends a literal here-string; embed data as base64 JSON instead
- Two KQL restrictions on the same property separated by a space are OR-ed — a range needs AND2026-10-29KQL joins restrictions on the SAME managed property with OR when only a space separates them, so a size or date range written as two restrictions matches every item; write ranges with explicit AND or a..b
- SharePoint Search finds nothing for a question in an inflected language — add prefix-wildcard stems, and never turn zero hits into "latest documents"2026-10-29KQL is implicit AND and matches exact word forms, so Czech inflected forms miss; add a stem* variant in code, relax before giving up, and never serve a date-sorted inventory as sources for a specific question
- POST /fields rejects a subtype property like RichText unless the body names the subtype2026-10-28{ FieldTypeKind: 3, RichText: false } without @odata.type is read as SP.Field and fails with 400 – plain text columns in the same loop succeed, so the list ends up half-built; use CreateFieldAsXml or annotate the type
- Audio in an SPFx web part (SharePoint and Teams): playback may be refused, the feature must not stop2026-10-28SPO's CSP has no media-src today, so MP3 from your CDN plays; start playback from a click and fall back to silent timing on NotAllowedError, 404 or mute
- Azure TTS HD voices are generative — the same sentence gives a different recording each time, so verify every file by transcription2026-10-28DragonHD output varies per call and sometimes garbles a term; transcribe each MP3 with fast transcription and regenerate on a miss. Use for a non-native language, playbackRate instead of the unsupported , and honor…
- DecompressionStream throws away the whole result when bytes follow the compressed data2026-10-28Inflating a PDF FlateDecode stream in the browser fails completely because a line break sits between the data and endstream; trim trailing CR/LF and read chunk by chunk, keeping what arrived before the error
- FirstUniqueAncestorSecurableObject has no type in odata=nometadata — tell web, list and item apart by the shape of the answer2026-10-28The endpoint returns a web, a list or a list item depending on where inheritance breaks, and with odata=nometadata nothing names the type; classify by properties (FileSystemObjectType = item, BaseTemplate = list…
- A missing attachment returns 400, not 404 – an "is it there?" check by status code reads "not there" as a failure2026-10-27AttachmentFiles('name') on a missing attachment returns 400 ArgumentOutOfRangeException; check existence from the attachment list
- Migrating list items with original authors, dates — and their version history2026-10-27Copy and Move does not do lists, but REST does the job item by item — AddValidateUpdateItemUsingPath takes Author, Editor, Created and Modified at creation (one call, one version), version history can be replayed with…
- Reindex a library from code works even on a no-script site — the root folder's property bag is writable, the web's is not2026-10-27Bumping vti_searchversion on the library's RootFolder property bag via CSOM succeeds on sites with custom scripts disabled (unlike the web property bag); find the library from any item URL with GetWebUrlFromPageUrl +…
- Multi-line text in a document library stops at 255 characters2026-10-27A REST MERGE stores 70k characters, but ValidateUpdateListItem rejects anything over 255 unless the column has UnlimitedLengthInDocumentLibrary – set it at creation or PATCH it later
- A CDN-hosted extension bundle may only import modules its App Catalog manifest declares2026-10-26Replacing an extension's stable-named bundle on the CDN without a new .sppkg works only while its define([...]) lists modules already in the installed manifest's scriptResources — one new value import and the extension…
- A REST write over 2 MB fails with "The request message is too big"2026-10-26SharePoint Online rejects any REST request whose body exceeds 2,097,152 bytes (after JSON escaping, in UTF-8). A multi-line text field in a list holds far more than that – the cap is the request, not the field – so…
- Turn a library URL someone pasted into web + library + folder2026-10-26SP.Web.GetWebUrlFromPageUrl, called on the CURRENT web, resolves the web of any URL in the tenant (other site collections too, 404 for a missing site); strip Forms/…aspx, prefer the ?id= folder, take the first segment…
- pdf.js: "Cannot use the same canvas during multiple render() operations" on resize2026-10-26A React effect that re-renders a PDF page on every resize starts a second render() before the first finishes; cancel the running task in cleanup and chain renders so they never overlap
- JoinHubSite silently moves a site that already belongs to another hub2026-10-25Calling JoinHubSite on a site that sits in hub A returns 200 and the site is in hub B at once — no unjoin step, no warning, so any "apply hub" plan must read the current hub first
- An archived site returns 423 on every Graph read — keep the site collection ID to reactivate it2026-10-25archivalDetails is unreadable once archived; POST /sites/{host},{siteCollectionId}/unarchive still works
- The memberOf operator in dynamic group rules stops working on 3 November 2026 — groups freeze instead of failing2026-10-25Entra ends the memberOf preview operator in dynamic membership rules on 3 Nov 2026 (MC1448379): affected groups, dynamic admin units and auto-assignment policies keep their last membership and never update again.…
- Adding or removing a group member via Graph needs the object ID — a UPN returns 400 "Invalid object identifier"2026-10-24POST /groups/{id}/members/$ref and DELETE /groups/{id}/members/{id}/$ref accept only the user's object ID (GUID); a UPN from a people picker returns 400 Invalid object identifier — resolve it with GET…
- Message Center via Graph — with $orderby you may get one page and no nextLink; page with $skip2026-10-24messages?$top=100&$orderby=… returned 100 posts without @odata.nextLink; $top + $skip returned all 441
- The public Microsoft 365 roadmap JSON has no CORS headers — an SPFx web part can't fetch it2026-10-24releasecommunications/api/v1/m365 answers 200 without Access-Control-Allow-Origin; proxy it server-side
- CreateCopyJobs: the library root is refused, progress logs are handed out once, and JobWarning is not a failure2026-10-22Passing a document library's root folder URL to CreateCopyJobs fails with HTTP 500 "Null value for source item" while a subfolder URL copies the folder with its content; several file names containing the hash sign…
- CreateCopyJobs with MoveButKeepSource keeps version history, timestamps and authorship — and how to actually prove it2026-10-22The server-side Copy and Move job preserves all versions, Created/Modified and Created By/Modified By, leaves the source in place, and is callable from the browser under delegated auth; omitting AllowSchemaMismatch is…
- Parentheses in an Azure CLI --query argument break az.cmd on Windows ("-o was unexpected at this time.")2026-10-21On Windows az is a batch file; a JMESPath query with ( ) and no spaces reaches cmd unquoted and breaks its IF block – return plain names and count in PowerShell
- A network drop through the Microsoft Graph JS client looks like an HTTP error with status -12026-10-18msgraph client wraps a failed fetch as GraphError statusCode -1, code TypeError – detect it, don't report "permission denied"
- Microsoft To Do rejects $select on lists and tasks — 400 invalidRequest (RequestBroker--ParseUri)2026-10-15Since Oct 2026 /me/todo/lists and /tasks return 400 for any $select except id; drop $select, keep $top/$filter, and measure 400s call by call before trusting a docs-based theory
- RAG finds nothing that SharePoint Search finds — the reasoning model spent the whole token cap thinking2026-10-12GPT-5/o-series count hidden reasoning in max_completion_tokens; a small cap on the query-generator call returns empty text (HTTP 200), and a raw-question fallback ANDs every word in KQL
- Item-level edit rights cover every field – don't trust status, approver or link fields the user can write2026-10-09Unique permissions on an item don't separate fields: whoever may edit it can set Status, Approver or a lookup Id via REST – derive trust from admin-only data and version history
- The ETag key is @odata.etag in OData v4 – reading odata.etag silently turns IF-MATCH into *2026-10-09SPHttpClient speaks OData v4: the item ETag comes as @odata.etag; reading odata.etag yields undefined and your IF-MATCH protection quietly disappears
- signInActivity without Entra ID P1 — the retry without it turns "not measured" into "0 inactive users"2026-10-09Selecting signInActivity on /users fails with 403 in tenants without Entra ID P1/P2; the common fallback (retry without the property) makes every user look "never signed in" or gets skipped, so inactive-user and…
- Adding an attachment changes the item's ETag – the next MERGE with the old ETag fails with 4122026-10-09AttachmentFiles/add changes the item ETag; re-read before an IF-MATCH update
- Guests cannot join a Teams shared channel — only people from another Microsoft 365 organisation can2026-10-07Shared channels admit external people only through B2B direct connect between two Entra tenants; a guest account cannot be added, so a partner without their own Microsoft 365 needs a different design
- Contribute on the web lets a role edit and delete the pages of the site — including the page your app lives on2026-10-06Modern pages are items in the Site Pages library, which inherits from the web, so a group you give Contribute on the web "so it can write list items" can also edit and delete every page; withholding Manage Lists does…
- GetUserEffectivePermissions ignores the user's Entra security groups — and Full Control's effective mask is not the role's mask2026-10-05Asked on behalf of another user, GetUserEffectivePermissions counts Microsoft 365 group membership but not Entra security group membership — directly assigned or nested in a SharePoint group, still after 40 s — so it…
- A date in a group header is the reader's display string, not a date2026-10-05@group.fieldData of a Date field is text in the reader's locale; reformat only when the shape matches
- Looking up a field that does not exist returns 400, not 4042026-10-05fields/GetByInternalNameOrTitle on a missing field answers 400; test existence with a $filter instead
- An "add what's missing" permission sync turns every change of owner into a leak — the previous owner keeps access2026-10-04Idempotent grant-only re-sync is safe at item creation but not when an item moves to another customer or team — the old group stays on the item; remove by principal Id, keep a protected set, and verify with a second…
- An evidence record whose "who" is written by the browser proves nothing — compare it with the server-stamped Author, and compare on the sign-in name too2026-10-04Append-only lists let any contributor add a row with someone else's name in a text column; Author is stamped by SharePoint. Compare the two — but against Author/Name (the sign-in claim) as well, or every user whose…
- Putting an Image web part on a modern page via REST — the control JSON that renders, with a link2026-10-04Out-of-the-box Image web part (d1d91016-…) in CanvasContent1: file ids in properties + customMetadata, the URL in serverProcessedContent.imageSources, the click target in links.linkUrl; works in a full-width section…
- A drop box for sensitive files — a document library can't do it, a list with ReadSecurity 2 and attachments can (measured, including the direct attachment URL)2026-10-01Giving someone write access to a protected library folder also lets them read every file in it; a list with ReadSecurity = 2, Contribute for the senders and Edit for the reviewers lets people send files they alone can…
September 2026 62 new
- A docked side panel floats in mid-air on the newer SharePoint layout: .sp-App-bodyContainer is not there2026-09-30A Copilot-style side panel narrows the SharePoint page by shrinking .sp-App-bodyContainer. On the newer page chrome (left app bar with Discover/Publish/Build) that container does not exist, so the docking code silently…
- SPFx in Teams — the current user's numeric ID belongs to the host site, not to your data site2026-09-28legacyPageContext.userId in a Teams personal app is the tenant root site's ID; written as the user's ID on another site it can silently point to someone else
- Counting a site's audience from its associated groups silently misses nested groups2026-09-28Owners/Members/Visitors often contain Everyone except external users or the Microsoft 365 group claim (PrincipalType 4); keeping only PrincipalType 1 rows turns a whole company into one or two people – treat any nested…
- Deduplicating events from an external API with a timestamp watermark silently drops simultaneous and late events2026-09-28When you pull activity events (opens, clicks, audit entries) in batches with an overlapping cursor, "skip anything not newer than the last counted event" throws away a second event with the same second-precision…
- Overwrite=true into a folder shared by many records silently replaces — and takes over — another record's file2026-09-26Uploading with Files/AddUsingPath(…,Overwrite=true) under a user-supplied file name into a folder that holds documents of many records (cases, orders, tickets) lets a second file with the same generic name (such as…
- A deleted or moved test keeps running from stale lib-commonjs — the SPFx rig's --clean never touches that folder2026-09-26In SPFx projects built with Heft, Jest runs the compiled tests in lib-commonjs, but the rig's clean step deletes dist, lib, release, generated .scss.ts/.resx.ts files and parts of temp (and jest-output for the test…
- Printing from a web part gives a blank page when the print CSS hides body > * and the print layer lives inside the web part2026-09-26One way to print a report from an SPFx web part is to hide everything in print (body > * { display: none }, so the SharePoint suite bar, navigation and footer stay out) and show only a dedicated print layer. If that…
- global.navigator = dom.window.navigator is ignored on Node 21+ (or throws) — your jsdom test runs with Node's navigator2026-09-26Node 21 added a global navigator that has a getter and no setter, so the classic hand-made jsdom setup line is silently ignored (strict mode throws a TypeError) and the test sees Node's userAgent (e.g. "Node.js/24")…
- "Your data stays in the region you chose" — for Azure OpenAI the deployment TYPE decides where prompts are processed, not the region2026-09-25A GlobalStandard deployment in an EU region may process prompts in any Azure region; only Data Zone (EU Data Boundary) or regional Standard keep processing in the zone or geography — write data-location claims from the…
- A test that plants a git hook without chmod passes on Windows and fails on Linux CI2026-09-25Git ignores a hook without the executable bit, but Git for Windows does not check that bit and runs a hook that starts with #!/bin/sh, so a fixture that writes .git/hooks/pre-commit with writeFileSync blocks the commit…
- A fixed WEBSITE_CONTENTSHARE in your template can break production on the first template redeploy after a slot swap2026-09-25On a function app with deployment slots, WEBSITE_CONTENTSHARE isn't slot-sticky: a swap moves it together with the code. A template that pins the production value (say toLower(appName)) would point production back at…
- .funcignore pattern src/ also empties node_modules/*/src — the deployment succeeds, the functions don't load2026-09-25Azure/functions-action applies .funcignore with gitignore semantics to every path in the package, so src/ or test/ without a leading slash also empties those folders inside node_modules. A dependency whose entry file…
- GitHub Actions OIDC login to Azure fails with AADSTS700213 in repositories created after 15 July 20262026-09-25New GitHub repositories send the OIDC subject as repo:owner@ownerId/repo@repoId:…, so an Azure federated credential written in the classic repo:owner/repo:… form never matches and azure/login fails with AADSTS700213.…
- Rolling out required tokens on your own API: the "calls without a token" counter measures every client, not just the app you fixed2026-09-25You add Entra ID token validation to an API your SPFx solutions call, ship it in soft mode and wait for "calls without a token" to reach zero — it never does, because a shared npm package, a second solution, a…
- A "grant it for me" button cannot work in a web part — not even for a Global Administrator2026-09-25A delegated call gets the intersection of the user's rights and the app's grants, so the admin at the keyboard adds nothing; writing the grant would take at least DelegatedPermissionGrant.ReadWrite.All approved for the…
- process.exit() right after fetch() can crash Node on Windows, and the exit code then lies2026-09-25On Windows (seen on Node.js 24), process.exit() right after the built-in fetch() sometimes aborts on a libuv assertion (UV_HANDLE_CLOSING) and ends with a crash code (3221226505, shown as 127 in Git Bash), so a check…
- For license information please see … leads to a 404 — the publish step left the bundle's .LICENSE.txt behind2026-09-25webpack moves third-party license comments into .js.LICENSE.txt and leaves only a pointer in the bundle; a publish step that copies *.js, or an allowlist .gitignore, ships the code without the texts MIT and BSD…
- The Microsoft Graph JS client sends $filter values unencoded — & splits the query, # cuts it off2026-09-24.filter(), .query() and .api('…?…') pass the value into the URL as-is (SDK 3.0.2, also under SPFx MSGraphClientV3): # cuts the query, & splits it and .api() even moves $top into the filter; double apostrophes, then…
- A count over a ReadSecurity 2 list is only the reader's share — and the bit that says "sees everything" is Manage Lists alone2026-09-24Item-level read security filters rows silently, so a client-side count or ranking is the reader's own rows; show it only with ReadSecurity = 1 or Manage Lists in the reader's mask, and don't also demand Override List…
- SharePoint REST has no increment — a "+1" computed from the count you read at page load loses every vote cast in between2026-09-24A MERGE writes a value, so count + 1 from what the page loaded, sent with IF-MATCH: *, overwrites every vote cast since that page load; count distinct AuthorIds of per-user rows, or read fresh and write with the item's…
- A # or % in a file or folder name — the classic …Url APIs cannot reach it, and the old writes quietly save %252026-09-24The classic …ServerRelativeUrl lookups, Files/add(url=), folders/add, moveto and copyto cannot reach it even encoded: 404/400, Exists: false for a folder that exists, and writes that answer 200 but save a literal %25…
- stopPropagation in onClick does not stop the keyboard — a clickable row swallows Enter and Space of the buttons inside it2026-09-24A clickable row with onKeyDown also receives the Enter/Space of its inner buttons and checkboxes, so their action is cancelled (or runs twice) and the detail opens; react only when e.target === e.currentTarget
- A component from a linked package throws "Invalid hook call" in Jest — the test loaded a second copy of React2026-09-24Jest resolves a file:/junction package by its real path, so the package's require('react') finds a second copy; map react and react-dom to the app's copy (the SPFx build is unaffected — React is a platform component)
- TextEncoder is not defined before your first test runs — a dependency needs it at import time and jsdom does not have it2026-09-24jsdom has no Encoding API and a dependency that builds new TextEncoder() at module level dies on import, before beforeAll; import a polyfill module first or use setupFiles, and make the dependency lazy
- A decimal comma erases a Number column — Number('7,25') is NaN, JSON sends null, SharePoint answers 2042026-09-24Number('7,25') is NaN, JSON.stringify sends null, SharePoint answers 204 and empties the column (measured: 7.25 → null on edit); parse text input comma-aware and reject NaN
- List and library pages run a stale extension bundle from Cache Storage for days2026-09-24Stable (unhashed) bundle URL = list and library pages can run a days-old copy from the Lists app's own Cache Storage (Lists-odsp-web-prod_*), whatever Cache-Control says; keep the stable file a tiny loader and load…
- A newsletter looped over /me/sendMail is not bulk e-mail — and ACS Email is no longer the way out2026-09-24Per-mailbox and tenant limits, bulk mail through Microsoft 365 "isn't a supported use", JSON sendMail can't set List-Unsubscribe, ACS Email retires 2028; keep Graph for personal batches, send newsletters through an ESP…
- Retry only fast failures — a gateway error after 230 seconds is a timeout, not a hiccup2026-09-24The 502/503/504 a client rightly retries for transient failures also comes back when a request ran out of time (Azure Load Balancer returns 502 after 230 s), and retrying that multiplies the wait (3 × ~230 s) and the…
- A column called MyField0 appears — a throttled existence check or two web parts provisioning at once2026-09-24POST /fields with a taken name succeeds with a numeric suffix; 429 read as "missing", a cached check or two concurrent web parts each make a twin — three-state check, single run per site, name check after the create
- An unencoded # in a $filter value cuts the URL — SharePoint gets half a query and answers 4002026-09-24The browser drops everything after # as a fragment, SharePoint gets an unterminated literal and answers 400; guest UPNs (#EXT#) always hit it; & cuts the expression and a raw + arrives as a space, so a valid literal…
- window.open with noopener returns null even when the tab opened — so your fallback runs every time2026-09-24Code that reads null as "blocked" runs its fallback every time: the e-mail opens twice (Outlook on the web and mailto:), the print window stays empty; open without the feature and set w.opener = null
- AddValidateUpdateItemUsingPath answers 200 when it creates nothing — while a write to a missing column is a loud 4002026-09-24Field errors sit inside a 200 and no item is created; a write to a missing column is a 400 on every path, never a silent drop
- Promise.all discards the soft reads it was waiting for — one failing main read leaves every picker loading forever2026-09-24A failing main read rejects the batch and the soft reads' results and failure flags never reach the pickers; settle each read on its own
- A Choice value your field does not know is stored anyway — so a drifted vocabulary never announces itself2026-09-24No 400, no error to swallow: a drifted vocabulary never shows at runtime; machine-check the type-to-schema contract
- Setting process.env.TZ inside Jest does not change the time zone2026-09-24A test, setupFiles and setupFilesAfterEnv write into the sandbox's copy of process.env, so day-boundary tests pass only on machines already in the right zone; pin it in globalSetup, assert the offset, and run once…
- A comma in a Graph permissions table can mean AND — searching Teams messages needs two scopes2026-09-24Searching chatMessage needs Chat.Read and ChannelMessage.Read.All; the 403 spells it out, the table does not (+ webUrl vs webLink from the same endpoint)
- E-mail HTML built like a web page falls apart in Outlook2026-09-24Classic Outlook renders with Word: no flexbox, rounded corners or gradients, so white text on a gradient vanishes; tables, solid colours, literal values, a full document, and under ~102 KB for Gmail
- Purview audit objectIdFilters can return nothing — silently2026-09-24Narrowed to one library: 0 records, no error; without the filter 1,000 records, 38 of them for that library — ask for a window, filter by object locally, A/B every server-side filter
- A formatter renders empty in the tab you are iterating in — verify in a fresh tab2026-09-24After many REST writes the working tab shows even valid formatters blank while a fresh tab renders them; one tab per version, a scratch view, and simple formatters on fragile lists
- View formatting drops CSS gradients — use a solid background-color2026-09-24background is not on the style allowlist and a gradient in background-image did not survive either; a white initial on a gradient avatar turns invisible, so use a solid background-color
- The tenant root site is not necessarily readable by everyone2026-09-24Measured: unique permissions, no Everyone except external users, an ordinary employee's mask High=0, Low=0; don't anchor a must-work-for-everyone mechanism there, measure with getusereffectivepermissions
- moveto succeeds and your code reports a failure — action endpoints return an empty body2026-09-24Action endpoints (moveto, removebyid) return an empty body, so response.json() throws after the operation happened and invites a retry; decide by status, parse only what you read
- A folder's Files collection rejects a two-level $expand2026-09-24ListItemAllFields/Editor 400s there; take ModifiedBy/Author from the file, and list one level through the folder API rather than a FileDirRef filter
- A Hyperlink column takes an object, not a string2026-09-24It reads back as { Description, Url } ([object Object], React #31) and a plain string fails the whole save with 400; one helper each way, 255-character address limit, scheme allowlist
- webUrl + a server-relative URL doubles the site path2026-09-24Survives for months as a display value or grouping key and breaks the first time it becomes a filter; build object URLs from the origin in one helper
- Search ParentLink points at a library view, not at the library2026-09-24Often …/Forms/AllItems.aspx, so used as a path it empties a Path: filter and can send a save into Forms while a GetList probe still passes; normalize on read and on write
- A command set's commands are fixed in its manifest2026-09-24title, iconImageUrl, visible and disabled change at runtime, new commands need a new .sppkg; ship one entry that opens your own menu, or reserve hidden slots (and keep their titles honest)
- A library component loaded from your own manifest fetches its lazy chunks from that manifest's folder2026-09-24SPComponentLoader.loadComponent + a relocated manifest: without the chunk.* files next to the bundle every import() 404s on first use, which an open-the-app smoke test never exercises
- An overwritten script with a stable name keeps serving the old code2026-09-24max-age=600 on GitHub Pages, a memory cache shared by same-site tabs and SharePoint's service worker; keep stable files thin, test with cache: 'reload' and every tab closed, and don't read transferSize of a…
- An SPFx chunk's file name is not its content — realContentHash is off2026-09-24SPFx builds with realContentHash: false, so a byte-identical chunk can get a new name (measured) and nothing rules out the reverse; deduplicate by bytes or git blob and never overwrite a published file
- A GitHub Pages CDN without .nojekyll freezes on its last good build2026-09-24Branch builds run Jekyll unless .nojekyll exists; a growing bundle host ended in a bare "Page build failed." while the site kept serving the old build — read /pages/builds before pushing again
- A retention window computed from git history deletes the file you overwrite in place2026-09-24A stable loader keeps its add date and drifts out of "the last N releases"; protect by shape (no content hash), and remember the hard 1 GB Pages limit counts the published tree
- A setup marker that measures only part of the step freezes a half-provisioned site forever2026-09-19The success flag measured the id lookups, not the addroleassignment POST, so a 403 froze a site with groups that carry no permission level at all
- Your zip-bomb guard reads a private JSZip field — and fails open on the next upgrade2026-09-19entry._data.uncompressedSize is an implementation detail, and undefined → allow turns the next library upgrade into a silent loss of protection; read the declared sizes from the ZIP central directory instead
- REST DELETE on a list item is permanent — recycle() is the bin2026-09-19The usual delete call skips BOTH recycle bins; /items(id)/recycle() is what a “restorable for 93 days” promise needs
- A formatter that returns its raw input is a hole in your escaping2026-09-18The unhappy branch returns the value verbatim; about:blank inherits your origin
- A batch file move must be grouped by file, not by the record that points at it2026-09-18When records share a file URL, iterating records moves it once and 404s on the rest; group by file, write the new URL to every record, and adopt a file already at the target on a rerun
- Azure OpenAI 429 on a single request is a TPM ceiling, not a busy service — measure size, not frequency2026-09-17One request whose prompt exceeds the deployment's TPM allowance can never fit the window, so retrying is futile — a sub-second rejection means "over the ceiling", not "busy"; separate the two with a small/large request…
- Retry-After does not survive CORS — a header you send and the client reads can still arrive as null2026-09-17A cross-origin response exposes only the headers named in Access-Control-Expose-Headers plus a short safelist, so an API that sends Retry-After and a client that reads it still meet at null — both ends look right and a…
- pageContext.cultureInfo returns the web language sometimes and the user language other times2026-09-17The same page loads English once and Czech the next time; cache the resolved language per web instead
- RecycleByID sends a file version to the recycle bin — DeleteByID does not2026-09-17The two removal methods on /Versions differ: permanent vs. site recycle bin (ItemType 2, restorable); measured, with vid = major*512 + minor
- getfolderbyserverrelativeurl returns 200 for a folder that does not exist2026-09-17It answers HTTP 200 with {"Exists": false} (and ListItemAllFields 200 with {"odata.null": true}), so a check on response.ok skips creating the folder and the next call 404s inside breakroleinheritance; measure the…
Recently reviewed
Existing articles checked and updated in the last 30 days.
- The browser cache answers your read-after-write check — with a 200reviewed 2026-11-12The same URL read on both sides of a write is served from the browser cache, so res.ok guards pass on stale state; a cached existence check makes POST /fields create a duplicate column and report success, and an…
- Previewing library files in your own app: every format behaves differentlyreviewed 2026-11-12PDF embeds directly, Office needs WOPI by {UniqueId}, HTML is served as an attachment and never renders from src; SVG and HTML must never be framed from your own origin (uploader script runs in the viewer session) and…
- File versions come back oldest-first, so $top truncates the newest onesreviewed 2026-11-10/Versions is ascending, so $top drops the NEWEST ones; sorting the result descending afterwards hides it; $orderby=ID desc IS honoured together with $top (measured), and the list never contains the current version
- PS 5.1: @(pipeline ConvertFrom-Json) keeps the array wrapped — foreach runs once, ConvertTo-Json emits {value:[…],Count:n} garbagereviewed 2026-11-07@() around the pipeline doesn't enumerate: foreach over it runs ONCE with the whole array, and a later + nests the array so ConvertTo-Json writes {value:[…],Count:n} garbage; fix with @((ConvertFrom-Json …))
- Importing third-party CSS with url(images/...) breaks the SPFx buildreviewed 2026-11-05url(images/...) without ./ kills the build; inject a instead
- DateTime fields — write full ISO with a time zone, derive the day locallyreviewed 2026-11-04No-timezone writes 400; UTC reads shift the day; read a day in the zone it was written in — including noon-UTC dates at UTC+12 to +14; a bare date in $filter is UTC midnight, so le drops the last day of a range
- A mail-permission probe that can't tell "no mailbox" from "no consent" lies to adminsreviewed 2026-11-03/me/messages 404 MailboxNotEnabled* on mailbox-less accounts ≠ missing consent; three verdicts, and never cache a negative probe result
- Microsoft To-Do (/me/todo) needs an Exchange mailbox — admin accounts 404reviewed 2026-11-03404 "Item not found" on admin/cloud-only accounts is not a 403; Planner works without a mailbox
- Office files change their content hash when you PATCH metadata — property demotionreviewed 2026-11-01Metadata PATCH and copy jobs rewrite Office, .msg and .htm file bytes; key change detection on lastModifiedBy, never compare sizes exactly
- Telling a list's own columns from inherited ones — Hidden is not enoughreviewed 2026-11-01Hidden is not enough; FromBaseType + CanBeDeleted are what separate the list's own columns
- createfieldasxml ignores Name/StaticName — the internal name is derived from DisplayNamereviewed 2026-10-27createfieldasxml on a list ignores Name/StaticName unless you pass Options: 8 (AddFieldInternalNameHint); otherwise the internal name is escaped from the label – create with ASCII and rename, or use the hint to keep a…
- Created/Modified on a document library won't stick — and the API says 200 while ignoring youreviewed 2026-10-23A plain MERGE reports 204 and SharePoint overwrites both with "now"; ValidateUpdateListItem + bNewDocumentUpdate is the only path that holds, it wants the web's locale format (the error message tells you which), reads…
- PermissionKind is 1-based — decoding BasePermissions with 1 << kind invents a security findingreviewed 2026-10-20The flag for kind k is 1 << (k - 1), so 1 << k invents a security finding: Contribute appears to hold ManageLists (it holds ViewFormPages). Calibrate any decoder against a known level first, and note the tell — a…
- POST /views takes an SP.View body — ViewTypeKind fails, and @odata.type passes only under OData v4reviewed 2026-10-20ViewTypeKind from the creation-information docs 400s, and an @odata.type annotation passes only with OData-Version: 4.0; measured recipe for view + scope + column order