Troubleshooting
Solutions for common issues with Norrix CLI, SDK, and builds.
Authentication Issues
”Unauthorized” Errors
Symptoms:
- CLI commands fail with “Unauthorized”
- API returns 401 status
Solutions:
-
Check if you’re signed in:
norrix whoami -
Re-authenticate:
norrix sign-out norrix sign-in -
Verify organization:
norrix orgs current -
Check environment (prod vs dev):
norrix whoami # Production norrix --dev whoami # Development
API Key Issues
Symptoms:
- CI/CD builds fail with auth errors
- “Invalid or expired API key”
Solutions:
-
Verify key hasn’t expired:
- Dashboard → Settings → API Keys
- Check expiration date
-
Verify key has required scopes:
buildfor build operationssubmitfor submissionsupdatefor OTA updates
-
Check key is for correct environment:
- Production keys only work with
norrix.net - Dev keys only work with
dev.norrix.dev
- Production keys only work with
-
Ensure key is set correctly:
echo $NORRIX_API_KEY # Should show key value
Token Refresh Failed
Symptoms:
- “Failed to refresh token”
- Prompted to sign in frequently
Solutions:
-
Clear cached tokens:
rm -rf ~/.norrix norrix sign-in -
Check system time is correct (affects token validation)
Build Failures
Build Fails Immediately
Symptoms:
- Build status shows “failed” within seconds
- No build logs generated
Solutions:
-
Run with verbose mode:
norrix build ios release --verbose -
Check project builds locally first:
ns build ios --release -
Verify signing credentials exist and are valid
-
Check entitlements:
- May have hit monthly limit on Free tier
- Dashboard → Settings → Usage
iOS Code Signing Errors
Symptoms:
- “Code signing failed”
- “No matching provisioning profile”
- Certificate errors
Solutions:
-
Verify Team ID:
# Should be 10 alphanumeric characters norrix build ios release --team-id ABC123XYZ0 -
Check certificate expiration:
- Apple Developer Portal → Certificates
- Regenerate if expired
-
Verify provisioning profile:
- Matches bundle ID
- Includes correct certificate
- Not expired
-
For ASC API issues:
- Verify Key ID and Issuer ID
- Confirm .p8 file is unmodified
- Check API Key has Admin access
Android Signing Errors
Symptoms:
- “Keystore was tampered with”
- “Alias not found”
- Password errors
Solutions:
-
Verify keystore path:
ls -la ./path/to/keystore.jks -
Test keystore locally:
keytool -list -v -keystore ./path/to/keystore.jks -
Verify key alias exists in keystore
-
Check passwords are correct (no trailing whitespace)
Build Number Conflicts
Symptoms:
- “Build number already exists”
- App Store rejection for duplicate build
Solutions:
-
Use explicit build number:
norrix build ios release --build-number 50 -
Check existing builds in dashboard
-
Build numbers must always increase for App Store
OTA Update Issues
Update Not Detected
Symptoms:
- App shows no updates available
checkForUpdates()returnsupdateAvailable: false
Solutions:
-
Verify SDK initialization runs early:
// Should be in app.ts or main.ts, before app starts import { initNorrix } from '@norrix/client-sdk'; initNorrix({ updateUrl: 'https://norrix.net', checkForUpdatesOnLaunch: true, }); -
Check updateUrl is correct:
- Production:
https://norrix.net - Development:
https://dev.norrix.dev
- Production:
-
Verify update version is higher:
- Check
currentVersionvs update version - Must be semver greater
- Check
-
Check bundle ID matches:
- App bundle ID must match published update
-
Verify update was published successfully:
- Dashboard → Updates → Check status
-
Check whether the device quarantined it after a failed launch:
norrix.getQuarantinedUpdateIds();
Update Incompatible
Symptoms:
requiresStoreUpdate: true- “Native changes detected”
Solutions:
-
Check fingerprints:
norrix fingerprint compare --from <buildId> -
Review what changed:
- Plugin version updates?
- App_Resources changes?
- NativeSource modifications?
-
If changes are intentional:
- Publish a new store build
- Then resume OTA updates
Update Doesn’t Apply
Symptoms:
- Update downloads but app doesn’t change
- Same version after restart
Solutions:
-
Updates apply on app restart:
- Use
promptToRestartAfterInstall: true - Or call
norrix.applyUpdate(true)to force close
- Use
-
Check status callback:
statusCallback: (status, data) => { console.log('Status:', status, data); }; -
Verify update was installed:
- Status should reach
UPDATE_INSTALLED - Check for
ERRORstatus
- Status should reach
-
Check for HMR interference:
- Disable HMR in production builds
- SDK skips updates when HMR is active
Update Download Fails
Symptoms:
ERRORstatus with download message- Partial download
Solutions:
-
Check network connectivity
-
Verify URL hasn’t expired:
- URLs valid for 1 hour
- Retry check to get fresh URL
-
Check device storage:
- Sufficient space for update bundle
App Reverted to an Older Version After an Update
Symptoms:
- Devices report an older version than the update you published
statusCallbackreceivedSyncStatus.ROLLED_BACK- The same devices no longer pick the update up, even after several checks
What happened:
The update failed to launch before it displayed any content — an uncaught JavaScript error, or a bundle that never got the runtime as far as starting the app. The SDK quarantined it and relaunched into the newest bundle it trusts: the previous update if one is still installed, otherwise the store binary.
A quarantined update is never launched or installed again on that store binary. The device sends its id as excludeIds on every check, so the server stops offering it. This is deliberate: without it, the device would download the same broken bundle again on the next check.
Confirm it on a device:
norrix.getQuarantinedUpdateIds(); // ['update-1788917268839']Across your fleet, the device reports an ota_launch_failed event with the update id and the error, followed by ota_recovered naming the bundle it landed on. Both roll up in Dashboard → OTA Analytics → Rollbacks & Failed Launches, where Affected Updates lists each update id with its failure count and when it last happened.
Actions:
-
Deactivate the bad update in Dashboard → Updates, so devices that have not launched it yet stop downloading it
-
Reproduce the failure locally with a release build, which runs the same bundle the device did:
ns build ios --release ns run ios --release -
Publish a corrected update with a higher build number:
norrix update ios -V 1.0.1 -B 44Devices pick the new update up normally. Quarantine applies to the failed update id, not to the version.
Common causes:
- An uncaught error in module-level code that runs during bootstrap
- Missing or broken module imports in the bundled JavaScript
- Code that calls a native API the store binary does not contain
- Wrong environment configuration baked into the bundle
To retry a quarantined update (for example while debugging a rollout), set retryFailedUpdates: true and reactivate the update. Quarantine also clears on its own when the device installs a new binary from the store.
initNorrix({
updateUrl: 'https://norrix.net',
retryFailedUpdates: true, // debugging only
});Update Installed but the Label Shows the Old Version
Symptoms:
- Your in-app version label disagrees with what the app is actually running
- The label shows a new build number before a restart, or after a rollback
Cause:
The label is reading Norrix_OTA_Version / Norrix_OTA_BuildNumber from ApplicationSettings. Those keys describe the installed update — what the next launch will run — not what is executing now. They are kept for backward compatibility only.
Solution:
Build the label from getRunningUpdate():
const running = norrix.getRunningUpdate();
const label = `${running.version} (${running.buildNumber})`;
// And, if you want to tell the user a restart is pending:
const next = norrix.getInstalledUpdate();
const restartPending = !!next && next.id !== running.updateId;Nx Workspace Issues
Project Not Found
Symptoms:
- “No NativeScript projects found”
- “Project ‘x’ not found”
Solutions:
-
Ensure you’re in workspace root:
ls nx.json # Should exist -
Check project has
nativescript.config.ts:ls apps/my-app/nativescript.config.ts -
Verify
project.jsonexists with correct name:{ "name": "my-app" } -
Use
--projectflag:norrix build ios release --project my-app
Dependencies Missing
Symptoms:
- Build fails with import errors
- “Cannot find module ‘@myorg/shared’”
Solutions:
-
Run with verbose:
norrix build ios release --project myapp --verbose -
Check
tsconfig.base.jsonpaths:{ "compilerOptions": { "paths": { "@myorg/shared": ["libs/shared/src/index.ts"] } } } -
Verify libs are in Nx dependency graph:
npx nx graph -
Check for implicit dependencies in
project.json
Path Alias Issues
Symptoms:
- “Module not found: @myorg/utils”
- Works locally but fails in cloud
Solutions:
-
Ensure paths use correct format:
{ "paths": { "@myorg/utils": ["libs/utils/src/index.ts"] } } -
Check webpack aliases match tsconfig paths
-
Verify all path targets exist
Environment Variable Issues
Variable Not Injected
Symptoms:
- Build doesn’t have expected env var
process.env.MY_VARis undefined
Solutions:
-
Verify variable is set:
norrix env list -
Check project scope:
norrix env list --project my-app -
Ensure variable is declared in config:
// norrix.config.ts env: { variables: ['MY_VAR'], } -
Check subscription:
- Env variables require Pro tier
Secret Value Incorrect
Symptoms:
- Build uses wrong secret value
- API calls fail with auth errors
Solutions:
-
Re-set the variable:
norrix env set MY_SECRET "correct_value" -
Verify visibility is correct:
norrix env list # Shows visibility type
Getting Help
Information to Gather
When contacting support, include:
- Build/Submit/Update ID
- CLI version:
norrix --version - Error message (full text)
- Verbose output:
--verbose - Platform and configuration
Support Channels
- Free tier: Community forums
- Pro tier: Email support
- Enterprise tier: Priority support
Useful Commands
# Version info
norrix --version
# Current auth status
norrix whoami
# Current organization
norrix orgs current
# Verbose build
norrix build ios release --verbose
# Check fingerprint
norrix fingerprint ios
# Compare with build
norrix fingerprint compare --from <buildId>