OfficeDev / OfficeDev/Office-Addin-Scripts
LTSC 2024 Mac WefProcess rejects manually-registered dev catalog
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 194
- Forks
- 117
- Avg merge
- 1d 32m
- Merged PRs (30d)
- 2
Description
Summary
On Office LTSC 2024 Mac, Excel's WEF scanner has a hard gate that
silently strips externally-written BlockForMinor,
EntitlementsInvalid, and AppStates values from any catalog with
UniqueId="developer" on the next Excel launch. The result is that
the dev add-in can never be promoted to a WefProcess no matter
how completely the SQL row set + on-disk layout is backfilled by hand
or by tooling.
Environment
- Office LTSC Standard for Mac 2024, version 16.110.2, build 26062818
- macOS 15.5
- Any add-in registered with
office-addin-debugging(so
UniqueId="developer") - SQLite 3 access to
~/Library/Group Containers/UBF8T346G9.Office/MicrosoftRegistrationDB/MicrosoftRegistrationDB_19413899015.reg
Repro
# Pre: Excel is NOT running.
# Pre: dev catalog is registered (via office-addin-debugging start or
# equivalent). The catalog is at SQL node_id 17763 with
# UniqueId=developer.
# 1. Verify pre-state
sqlite3 "$DB" "SELECT name, type FROM HKEY_CURRENT_USER_values WHERE node_id=17763;"
# Expected: Entitlements, UniqueId (2 rows)
# 2. Backfill the 5 preconditions manually (full SQL + on-disk layout)
# (use any method: Python sqlite3, a third-party reg tool, etc.)
# After this step, dev catalog has: BlockForMinor, Entitlements,
# EntitlementsInvalid, UniqueId, AppStates child node with
# <aid>_<ver> value, AddinLifecycle OMEX_<cat>_<aid>_{1,2,4} entries.
sqlite3 "$DB" "SELECT name, type FROM HKEY_CURRENT_USER_values WHERE node_id=17763;"
# Now: 4 rows (BlockForMinor, Entitlements, EntitlementsInvalid, UniqueId)
sqlite3 "$DB" "SELECT node_id, name FROM HKEY_CURRENT_USER WHERE parent_id=17763;"
# Now: 1 child (AppStates)
ls -la "$WEF/<catalog-hash>/"
# Now: 10 subdirs (AppStates, AppDetails, ExtendedManifest, ...)
# 3. Launch Excel
open -a "Microsoft Excel"
sleep 15
# 4. Quit Excel
osascript -e 'tell application "Microsoft Excel" to quit'
sleep 5
# 5. Re-check SQL state
sqlite3 "$DB" "SELECT name, type FROM HKEY_CURRENT_USER_values WHERE node_id=17763;"
# Result: back to 2 rows (Entitlements, UniqueId) — preconditions stripped!
sqlite3 "$DB" "SELECT node_id, name FROM HKEY_CURRENT_USER WHERE parent_id=17763;"
# Result: 0 children — AppStates gone
ls -la "$WEF/<catalog-hash>/" 2>/dev/null
# Result: No such file or directory — on-disk layout deleted
# 6. Excel diagnostic log
# Path: ~/Library/Containers/com.microsoft.Excel/Data/Library/Logs/Diagnostics/EXCEL/Primary*.log
# Grep for the addin GUID or catalog hash: ZERO references.
# No WefProcess child was ever spawned during the entire 15s session.
Expected
After manually writing all 5 preconditions and recreating the on-disk
WEF layout, the dev catalog should be discoverable by Excel's WEF
scanner. WefProcess should spawn, the manifest should be read, and
the add-in should load.
Actual
Excel launches normally, no WefProcess child is created, the dev
server gets zero requests, and the diagnostic log is silent. After
Excel quits, the SQL rows I wrote (BlockForMinor,
EntitlementsInvalid, the AppStates child node, the per-addin
AppStates value) and the on-disk layout are all gone. Only the
Entitlements and UniqueId="developer" rows survive.
The same SQL writes + on-disk layout, if applied to a catalog with
UniqueId set to a value other than "developer", do persist across
Excel launches (verified by diffing against the Omex catalog
geLWvPTNy9pxk4xxzFEGHw== which has UniqueId=842d1cbc0a4605aa_LiveId
and retains all 4 values + AppStates child across launches).
Diagnosis
The WEF scanner on LTSC 2024 Mac has a hardcoded trust gate keyed off
UniqueId (or some adjacent value we haven't yet isolated). For
catalogs it doesn't trust (which includes any catalog with
UniqueId="developer"), it:
- refuses to install the manifest into the WEF pipeline
- silently strips the precondition rows on the next launch
- deletes the on-disk mirror
- spawns no WefProcess
This is not a check for cert chain / manifest signature / Entitlments
GUID validity (those are addressed in the related issue). The gate
fires before any of those checks.
The exact value of the gate has not been identified. Most likely
candidates (in order):
UniqueId="developer"is on a hardcoded deny-list- A
CatalogSourceREG_DWORD bit we haven't located in the SQL tree - An Apple
SecCode/SecTrustcheck on the Excel binary that the
dev catalog's child process would inherit
The CustomUIValidationCache value
e504fb41-..._developer.Microsoft.Excel.Workbook = 1099998353 does
survive and is present even before any backfill, so the manifest XML
itself is being parsed and validated by Excel.
Workaround tried
- Tried backfilling all 5 preconditions + on-disk layout before
launching Excel: still gets stripped on the first launch - Tried backfilling the on-disk layout to live at
Wef/{EC993EB3-...}/Omex/<catalog-hash>/(Omex-style nested path):
same result - Tried mirroring the manifest both at the on-disk path and as a
fs.ensureLinkSyncat the legacy~/Documents/wef/: legacy path
is no longer read by LTSC 2024 Mac - Tried flipping
DebugAddins=1at
HKEY_CURRENT_USER\Software\Microsoft\Office\16.0\Excel\Options:
no effect on dev catalog visibility - Tried
office-addin-debugging@5.1.6→6.1.1upgrade: byte-equivalent
Mac write path (dev-settings-mac.jsidentical between
office-addin-dev-settings@2.3.6and3.1.1)
Related
- See also:
office-addin-debugging 5.x / 6.x doesn't sideload on LTSC 2024 Mac(#1006) — this issue is the broader "tooling only
writes 2/6 SQL rows" framing of the same root cause - See also: Omex manifest signing not reproducible for non-Microsoft
add-ins (issue TBD) — the signature question is downstream of this
gate and is only relevant after this gate is bypassed
Additional verification rounds (2026-07-03, 12:00–12:04)
After filing the report above, I ran 3 more rounds to isolate the
gate. All 3 made incremental improvements but none unblocked
WefProcess spawn.
Round v2: decimal-string format for QWORD-like values
Discovery: the HKEY_CURRENT_USER_values.value column stores
decimal string representations of 8-byte integers, not raw
bytes — even when type=1 (REG_SZ) or type=11 (REG_QWORD).
E.g. the working Omex baseline has:
OMEX_geLWvPTNy9pxk4xxzFEGHw==_geLWvPTNy9pxk4xxzFEGHw==_1|1|19|8307396822173121467
Entitlements|11|18|134276099564810000
I had been writing 20 bytes of X'00' (raw zero) which the
scanner rejects. After re-writing the AppStates value and the
3 AddinLifecycle entries as decimal FILETIME strings
(e.g. 134275249473009060):
- All 5 SQL preconditions SURVIVED the launch (first time)
- WefProcess still did not spawn
- Dev server still got 0 requests
- New on-disk catalog still not created
Round v3: AddinLifecycle naming convention
Discovery: the 3 OMEX_*_*_{1,2,4} entries are catalog-level
(not addin-level). The format is
OMEX_<catalog-hash>_<catalog-hash>_<N>, with the catalog-hash
repeated, not the AID. My initial writes used
OMEX_<catalog-hash>_<aid>_<N> which is wrong.
After re-writing the 3 entries with the correct naming
OMEX_vai+V16+KDygsa7v22t_6Q==_vai+V16+KDygsa7v22t_6Q==_{1,2,4}:
- All 5 SQL preconditions survived (second time)
- WefProcess still did not spawn
Round v4: UniqueId=OmexAnonymous (anonymous mode)
Discovery: this Office install is running anonymously
(UserIdentityCache node 14680 has ExcelIsAnonymous=1 and
ExcelOmexUserIdentity=""). The 3 catalog UniqueId values
on the system are:
- Omex (14682):
842d1cbc0a4605aa_LiveId(synthetic LiveId, 20 chars) - Omex anonymous (14683):
OmexAnonymous(14 chars) - Dev (17763):
developer(9 chars, whatoffice-addin-debuggingwrites)
Changed dev catalog's UniqueId from developer to
OmexAnonymous to match the anonymous-mode Omex catalog:
- All 5 SQL preconditions survived (third time)
- WefProcess still did not spawn
- Dev server still got 0 requests
Conclusion after 4 rounds
The WefProcess gate is not in any of the following, all of
which I have now written and confirmed surviving the launch:
- SQL
BlockForMinor=0(REG_DWORD) - SQL
EntitlementsInvalid={guid}(REG_SZ, valid GUID) - SQL
AppStatessubtree with<aid>_<ver>REG_QWORD FILETIME value - SQL
AddinLifecycle3 entries with correct naming and decimal-string values - On-disk 5 per-addin files:
AppStates/,Tokens/,Html/,
Metadata/,TrustedApps/ UniqueIdformat (developervsOmexAnonymous— neither works)
The remaining gate is upstream of SQL + on-disk. Most likely
candidates (in order):
- Certificate trust chain — XAdES-T signed by
CN=Microsoft Corporation Third-Party App Distribution
(Microsoft-internal cert, see the related Omex-signing issue) - WebView2 trusted domain plist entry for 127.0.0.1:3000
- CatalogSource bit in a SQL key not yet located
- Apple entitlement / SecTrust check on the dev catalog
process
Diagnostic tooling gap: no WefProcess verbose log mode is exposed
to users. Microsoft-internal ETW events would help diagnose which
of these gates is firing, but they're not accessible from the
user-side.
Backups preserved (in case anyone wants to replicate):
- SQL pre-restore:
MicrosoftRegistrationDB_19413899015.reg.bak.pretest.1783047857 - SQL pre-Plan-B+C:
/tmp/plan-bc-pre-1783050972.bak - On-disk pre-Plan-C:
/tmp/plan-c-backup-1783050724.tar.gz
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by rerunning the documented SQLite and on-disk catalog reproduction, then inspect the mentioned dev-settings-mac.js write path and Excel Primary*.log diagnostics. Done means isolating the remaining WefProcess gate and identifying a repository change or confirmed external blocker that restores dev add-in sideloading on LTSC 2024 Mac.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, macos, sqlite
- Domain
- desktop, tooling
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100