{"record":{"id":"45cc9b3a79e111ec","repo":"laurent22/joplin","slug":"could-not-access-data-on-server-options-path","errorCode":null,"errorMessage":"Could not access data on server \"${options.path()}\"","messagePattern":"Could not access data on server \"(.+?)\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/lib/SyncTargetJoplinServer.ts","lineNumber":133,"sourceCode":"\t\t\t\tif (r) {\n\t\t\t\t\tconst parsed = JSON.parse(r);\n\t\t\t\t\tif (parsed) {\n\t\t\t\t\t\toutput.ok = true;\n\t\t\t\t\t\treturn output;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\t// Ignore because we'll use the next test to check for sure if it\n\t\t\t\t// works or not.\n\t\t\t\tstaticLogger.warn('Could not fetch or parse info.json:', error);\n\t\t\t}\n\n\t\t\t// This is a more generic test, which writes a file and tries to read it\n\t\t\t// back.\n\t\t\ttry {\n\t\t\t\tawait fileApi.put('testing.txt', 'testing');\n\t\t\t\tconst result = await fileApi.get('testing.txt');\n\t\t\t\tif (result !== 'testing') throw new Error(`Could not access data on server \"${options.path()}\"`);\n\t\t\t\tawait fileApi.delete('testing.txt');\n\t\t\t\toutput.ok = true;\n\t\t\t} catch (error) {\n\t\t\t\toutput.errorMessage = error.message;\n\t\t\t\tif (error.code) output.errorMessage += ` (Code ${error.code})`;\n\t\t\t}\n\t\t} finally {\n\t\t\tfileApi.requestRepeatCount_ = previousRequestRepeatCount;\n\t\t}\n\n\t\treturn output;\n\t}\n\n\tprotected async initFileApi() {\n\t\treturn initFileApi(SyncTargetJoplinServer.id(), this.logger(), {\n\t\t\tpath: () => Setting.value('sync.9.path'),\n\t\t\tuserContentPath: () => Setting.value('sync.9.userContentPath'),\n\t\t\tusername: () => Setting.value('sync.9.username'),","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/laurent22/joplin/blob/2654b33620775080d1d59c552259d41e33dad3d2/packages/lib/SyncTargetJoplinServer.ts#L115-L151","documentation":"Thrown by SyncTargetJoplinServer.checkConfig during a write/read round-trip test: it put('testing.txt', 'testing') then get('testing.txt') and the returned content is not 'testing'. This catches silent data corruption or server-side rewriting (e.g. a proxy that mangles bodies) that stat-only checks would miss.","triggerScenarios":"checkConfig() puts 'testing.txt', reads it back, and `result !== 'testing'`. Caused by an intermediate proxy rewriting content, a misconfigured Joplin Server returning HTML errors as 200, or a server that stores content under a different path than it reads.","commonSituations":"Server URL points to a reverse proxy that injects boilerplate; wrong base path so reads hit a different namespace than writes; server is actually a different Joplin Server instance than expected; encoding/charset conversion.","solutions":["Verify the server URL and base path in sync settings point to the real Joplin Server endpoint.","Check any reverse proxy (nginx, Cloudflare) for response body rewriting or charset overrides — disable auto-minify / Rocket Loader etc.","Ensure reads and writes resolve to the same path (no path-rewrite rules that differ for PUT vs GET).","Try a direct connection to the Joplin Server without the proxy to isolate the cause."],"exampleFix":"# before: Cloudflare in front of Joplin Server, rewriting bodies\n# after: in Cloudflare, disable 'Auto Minify' and 'Rocket Loader' for the Joplin Server route,\n# and confirm the sync URL is https://server/api/files/...","handlingStrategy":"try-catch","validationCode":"// Outside checkConfig, you can pre-flight with a manual round-trip.\nawait fileApi.put('probe.txt', 'x');\nconst back = await fileApi.get('probe.txt');\nif (back !== 'x') throw new Error('Server is rewriting payloads — check reverse proxy');\nawait fileApi.delete('probe.txt');","typeGuard":"const isPassthroughPayload = (sent, received) => sent === received;","tryCatchPattern":"try { await SyncTargetJoplinServer.checkConfig(options); }\ncatch (e) { if (/Could not access data on server/.test(e.message)) { /* inspect proxy / path config */ } else throw e; }","preventionTips":["Point sync directly at the Joplin Server API path; remove body-rewriting middleware (minify, Rocket Loader, charset override).","In front of the server, run a curl round-trip (PUT then GET) to catch silent rewrites before configuring Joplin."],"tags":["sync","joplin-server","network","configuration","data-integrity"],"backgroundTag":null,"analyzedSha":"2654b33620775080d1d59c552259d41e33dad3d2","analyzedAt":"2026-08-12T14:26:46.263Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}