{"record":{"id":"5546bbf75faf1a28","repo":"laurent22/joplin","slug":"user-is-not-authenticated","errorCode":null,"errorMessage":"User is not authenticated","messagePattern":"User is not authenticated","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/lib/SyncTargetDropbox.ts","lineNumber":73,"sourceCode":"\t\t});\n\n\t\tapi.on('authRefreshed', (auth: string|null) => {\n\t\t\tthis.logger().info('Saving updated Dropbox auth.');\n\t\t\tSetting.setValue(`sync.${SyncTargetDropbox.id()}.auth`, auth ? auth : null);\n\t\t});\n\n\t\tconst authToken = Setting.value(`sync.${SyncTargetDropbox.id()}.auth`);\n\t\tapi.setAuthToken(authToken);\n\n\t\tconst appDir = '';\n\t\tconst fileApi = new FileApi(appDir, new FileApiDriverDropbox(api));\n\t\tfileApi.setSyncTargetId(SyncTargetDropbox.id());\n\t\tfileApi.setLogger(this.logger());\n\t\treturn fileApi;\n\t}\n\n\tpublic async initSynchronizer() {\n\t\tif (!(await this.isAuthenticated())) throw new Error('User is not authenticated');\n\t\treturn new Synchronizer(this.db(), await this.fileApi(), Setting.value('appType'));\n\t}\n}\n","sourceCodeStart":55,"sourceCodeEnd":77,"githubUrl":"https://github.com/laurent22/joplin/blob/2654b33620775080d1d59c552259d41e33dad3d2/packages/lib/SyncTargetDropbox.ts#L55-L77","documentation":"Thrown by SyncTargetDropbox.initSynchronizer() when isAuthenticated() returns false. The Dropbox sync target needs a valid OAuth token stored under Setting `sync.<id>.auth`; without it the Synchronizer cannot be constructed and Dropbox sync cannot start.","triggerScenarios":"User enables Dropbox sync but has not completed the OAuth flow, or the stored token was revoked/expired. initSynchronizer() calls isAuthenticated() which returns false.","commonSituations":"First-time setup where the user skipped the auth wizard; token revoked via Dropbox app settings; long- unused install whose token expired; clock skew invalidating token checks.","solutions":["Open Joplin sync settings, pick Dropbox, and complete the OAuth authorisation flow again.","If auth keeps failing, revoke the app from Dropbox's Connected Apps page, then re-authorise in Joplin.","Confirm system clock is correct — large skew can invalidate OAuth responses.","After successful auth, retry the sync."],"exampleFix":"// before: initSynchronizer() throws 'User is not authenticated'\n// after: in Joplin UI\n// Tools -> Synchronisation -> Synchronisation target: Dropbox\n// Follow the OAuth link, grant access, then click 'Synchronise'.","handlingStrategy":"validation","validationCode":"// Check the stored Dropbox auth token exists and is non-empty before initSynchronizer.\nconst token = Setting.value(`sync.${SyncTargetDropbox.id()}.auth`);\nif (!token) throw new Error('Dropbox not authenticated — run the OAuth flow first');","typeGuard":"const hasAuthToken = () => !!Setting.value(`sync.${SyncTargetDropbox.id()}.auth`);","tryCatchPattern":"try { await syncTarget.initSynchronizer(); }\ncatch (e) { if (/User is not authenticated/.test(e.message)) { /* trigger OAuth re-flow */ } else throw e; }","preventionTips":["Gate the 'Start sync' UI on isAuthenticated() to avoid the throw entirely.","Periodically refresh the token; surface expiry to the user before it lapses."],"tags":["sync","dropbox","authentication","oauth"],"backgroundTag":null,"analyzedSha":"2654b33620775080d1d59c552259d41e33dad3d2","analyzedAt":"2026-08-12T14:26:46.263Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}