Troubleshooting
Required environment variables
| Variable | Example value | If missing |
|---|---|---|
LOGI_API_URL | https://api.1pass.dev | falls back to localhost:3000 → connection failure |
LOGI_CLIENT_ID | logi_xxxxxxxxxxxxxxxx | client_id missing 400 |
LOGI_CLIENT_SECRET | logi_secret_… | /oauth/token 401 |
LOGI_SCOPES (optional) | openid profile:basic email | the code default |
⚠️ Standardize all four on the same prefix (variants like ONE_PASS_* are possible). If even one differs, ENV.fetch falls back to the default.
One-minute self-check
# 1. logi server reachability
curl -I "$LOGI_API_URL/.well-known/openid-configuration"
# 2. confirm client_id registration
logi apps verify $LOGI_CLIENT_ID --redirect-uri "$YOUR_CALLBACK_URL"
# 3. open the authorize URL directly
echo "$LOGI_API_URL/oauth/authorize?response_type=code&client_id=$LOGI_CLIENT_ID&redirect_uri=$YOUR_CALLBACK_URL&scope=openid&state=test&code_challenge=test&code_challenge_method=plain"
# 4. device self-diagnosis (UA · in-app · AASA · deep-link)
open https://api.1pass.dev/diagnoseError → cause → fix
1. ERR_CONNECTION_REFUSED / blank screen in prod
Cause: LOGI_API_URL not injected into the prod env → falls back to http://localhost:3000.
# check on Render
curl -s "https://api.render.com/v1/services/$SERVICE_ID/env-vars" \
-H "Authorization: Bearer $RENDER_API_KEY" | jq '.[] | select(.envVar.key | startswith("LOGI"))'Fix: add LOGI_API_URL=https://api.1pass.dev to your deployment platform's env → redeploy.
2. Invalid redirect_uri
Cause A: the prod callback URL is not registered. Cause B: the app's tier is sandbox → only localhost/*.staging.*/*.test.* are allowed, and the prod domain is blocked. Cause C (most common): the custom domain is missing. You registered only the platform default (*.onrender.com) and left out the actual prod domain (www.example.com). Matching is an exact match on scheme + host + path (no substring/wildcard).
logi apps show $CLIENT_ID # check tier + redirect_uris
logi apps add-redirect $CLIENT_ID "https://www.example.com/auth/callback"
logi apps add-redirect $CLIENT_ID "https://example.com/auth/callback" # apex
logi apps add-redirect $CLIENT_ID "https://yourapp.onrender.com/auth/callback" # backupRecommendation: register both the custom domain and the platform URL (a backup for DNS/SSL incidents, and for migration cutover). Free plans allow 5 redirect URIs; Pro plans allow 20.
Sandbox promotion: developer console → Submit for review. For details, see Registering Apps.
3. /oauth/token 401 (invalid_client)
Causes:
LOGI_CLIENT_SECRETnot injected into the prod env- forgot to update the RP env after a secret rotation
redirect_urimismatch — it must match exactly at both the authorize and token steps (including scheme/port/trailing slash)
logi apps rotate-secret $CLIENT_ID # copy the printed secret straight into the RP env4. The native app won't open on Mac/iOS desktop (browser only)
Causes:
- Server-side 302 redirect — a Universal Link breaks the user-gesture across a redirect chain. On both iOS and macOS.
- macOS Safari browser-first — clicking a UL loads the page first and shows only an "Open in [app]" banner at the top (WWDC19 #717 / TN3155). Having to click once more to launch the app is normal.
- Same-domain UL suppression — clicking an
api.1pass.dev/...UL on anapi.1pass.devpage is ignored. Workaround: a cross-host bouncer — the server emits toopen.1pass.dev/auth(the Universal Link is clicked on a new origin, sidestepping same-domain UL suppression). Universal Links guide.
Fix: have the server pre-build the authorize URL and put it directly in an <a href>.
def new
state = SecureRandom.urlsafe_base64(32)
verifier, challenge = OnePassSsoService.generate_pkce
session[:one_pass_state] = state
session[:one_pass_code_verifier] = verifier
render inertia: "Auth/Login", props: {
one_pass_authorize_url: OnePassSsoService.authorize_url(
redirect_uri: auth_1pass_callback_url,
state: state,
code_challenge: challenge
)
}
end<a href={one_pass_authorize_url} data-turbo="false" rel="external">Log in with 1pass</a>⚠️ Pasting into the address bar and pressing enter does not trigger a UL. Always verify with an <a> click.
5. The native app opens, but the consent screen shows "failed to load"
Cause: a cold-start race. OAuthConsentView calls /api/v1/oauth/authorize/preview before SessionStore.bootstrap() injects the PAK, so it gets a 401.
Fix: defer presenting the sheet until after session.state == .signedIn (LogiApp.swift / LogiMacApp.swift):
private var oauthSheetBinding: Binding<IdentifiableRequest?> {
Binding(
get: {
guard case .signedIn = session.state else { return nil } // block the race
return IncomingOAuthRouter.shared.pending.map(IdentifiableRequest.init)
},
set: { value in
if value == nil { IncomingOAuthRouter.shared.clear() }
}
)
}6. It doesn't even work on localhost
curl http://localhost:3000/up
# OK → working / Connection refused → server not runningIn the logi directory, run bin/rails server or cd server && bin/dev.
7. Universal Link won't open on a TestFlight build
Cause: the entitlement applinks:api.1pass.dev?mode=developer was built/submitted with a Distribution profile. Per Apple (WWDC19 #717): "Apps signed for distribution on the App Store or TestFlight … cannot be used with this alternate mode." → ?mode=developer is silently ignored → the AASA association is not registered → swcd doesn't know the domain → it falls back to the browser.
# install state on a macOS device
sudo swcutil show | grep -A 8 "1pass.dev"
# normal: Status: approved/approvedFix:
ios/Sources/logi.entitlements+ios/project.yml:diff- applinks:api.1pass.dev?mode=developer + applinks:api.1pass.dev- Same for mac (
mac/Sources/LogiMac.entitlements+mac/project.yml) - Bump the build number by 1 → upload a new TestFlight build:bash
cd ios && make testflight cd mac && make testflight - Verify: in Safari normal mode, click an
<a>on a site on a different domain
?mode=developer is for local Xcode debug builds only. Toggle it with make dev-mode-on/off; never commit it.
🚫 Same-domain URL paste verification, and verification in Chrome/Firefox/Brave/Safari private mode, are all invalid.
8. "Nothing happens when I click the button" in an SPA router (Turbo/Inertia/Next/HTMX)
Symptom: clicking fires a single /auth/logi/start request and then stalls. Console shows Cross-Origin blocked. Opening it directly in a new tab works fine.
Cause: the client-side router intercepts the form/link and issues the request via fetch() → a cross-origin 302 → blocked by CORS → silent failure. The same happens with Turbo, Inertia <Link>, HTMX hx-get, Next <Link>, SvelteKit, and Remix.
curl -sI https://yourapp.com/auth/logi/start | grep -iE "^(HTTP|location)"
# if HTTP/2 302 + location is normal, it's 100% a client-side problemIf right-click → "open in new tab" works, that confirms it.
Fix (per stack):
<!-- Rails Hotwire/Turbo -->
<%= link_to "Log in with 1pass", logi_start_path, data: { turbo: false } %><!-- Inertia.js — no <Link> -->
<a href="/auth/logi/start">Log in with 1pass</a>// Next.js — no next/link
<a href="/api/auth/logi/start">Log in with 1pass</a><!-- Vanilla / other -->
<a href="/auth/logi/start" target="_top">Log in with 1pass</a>Principle: start OAuth only via native navigation (a full page load). Wrapping it in fetch/XHR kills it on the cross-origin 302.
In-app browsers (KakaoTalk/Naver/Facebook/Instagram/Threads)
Symptom: in an in-app WebView, Apple/Google login shows "browser not allowed" or a blank screen.
Remedy: work around it with an external-browser escape route (/open, /x/:code).
- Demo:
demo.1pass.dev/demo - Details (8 in-app environments): Public Clients · in-app browser escape
- iOS LogiAuth SDK: auto-escape → ASWAS fallback
- Android/Flutter/RN:
setPackage/url_launcher externalApplication/Linking.openURL
First-try app-to-app on the RP side: Mobile track Step 3.
Deployment platform env setup
Render
# PUT a single variable only (no collection PUT — it replaces everything)
curl -X PUT "https://api.render.com/v1/services/$SERVICE_ID/env-vars/LOGI_API_URL" \
-H "Authorization: Bearer $RENDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"value": "https://api.1pass.dev"}'
curl -X POST "https://api.render.com/v1/services/$SERVICE_ID/deploys" \
-H "Authorization: Bearer $RENDER_API_KEY" \
-d '{"clearCache": "do_not_clear"}'Vercel
vercel env add LOGI_API_URL production
vercel --prodFly.io
fly secrets set LOGI_API_URL=https://api.1pass.devDebugging
Rails.logger.info "[logi] authorize_url=#{url}"
Rails.logger.info "[logi] token_response=#{tokens.except('access_token', 'refresh_token').inspect}"logi token inspect <access_token>When attaching logs, include only the client_id, redirect_uri, and HTTP status. Never the access_token/secret.