{"record":{"id":"44e3992e8fc4454a","repo":"toeverything/AFFiNE","slug":"caldav-provider-not-found","errorCode":"caldav_provider_not_found","errorMessage":"GraphQL bad request, code: caldav_provider_not_found, CalDAV provider is not available.","messagePattern":"GraphQL bad request, code: caldav_provider_not_found, CalDAV provider is not available\\.","errorType":"exception","errorClass":"GraphqlBadRequest","httpStatus":400,"severity":"error","filePath":"packages/backend/server/src/plugins/calendar/service.ts","lineNumber":207,"sourceCode":"  }\n\n  async linkCalDAVAccount(params: {\n    userId: string;\n    input: LinkCalDAVAccountInput;\n  }) {\n    const caldavConfig = this.config.calendar.caldav;\n    if (!caldavConfig?.enabled) {\n      throw new GraphqlBadRequest({\n        code: 'caldav_disabled',\n        message: 'CalDAV integration is not enabled.',\n      });\n    }\n\n    const preset = caldavConfig.providers.find(\n      provider => provider.id === params.input.providerPresetId\n    );\n    if (!preset) {\n      throw new GraphqlBadRequest({\n        code: 'caldav_provider_not_found',\n        message: 'CalDAV provider is not available.',\n      });\n    }\n\n    const provider = this.requireProvider(CalendarProviderName.CalDAV);\n    if (!('discoverAccount' in provider)) {\n      throw new GraphqlBadRequest({\n        code: 'caldav_provider_unavailable',\n        message: 'CalDAV provider is not configured.',\n      });\n    }\n\n    const discovery = await (\n      provider as CalendarProvider & {\n        discoverAccount: (input: {\n          preset: CalendarCalDAVProviderPreset;\n          username: string;","sourceCodeStart":189,"sourceCodeEnd":225,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/591f874dad30887a80143a061a44bd3ca7ee3299/packages/backend/server/src/plugins/calendar/service.ts#L189-L225","documentation":"Thrown by the calendar service's CalDAV account discovery when CalDAV integration is enabled but the providerPresetId sent in the mutation input does not match any entry in config.calendar.caldav.providers. The server looks the preset up by exact id equality before it can build a CalDAV client, so any unknown or stale id is rejected as a GraphQL bad request with code 'caldav_provider_not_found'. It is purely a config/input mismatch, not a network failure.","triggerScenarios":"Calling the CalDAV discoverAccount mutation with a providerPresetId that is not one of the configured preset ids (e.g. 'fastmail' when only 'nextcloud' is defined); the client cached a preset id from an older server config; a typo or trailing whitespace in the id; the operator removed/renamed a preset in the server config and clients still send the old id.","commonSituations":"Self-hosted deployments where the admin edited calendar.caldav.providers but did not restart or clients kept stale preset lists; frontends populated from docs defaults that differ from the deployed config; environments where CalDAV is enabled but the providers array is left empty.","solutions":["Inspect the server's calendar.caldav.providers config and copy the exact provider.id you want to use into providerPresetId.","Re-fetch the provider preset list from the API the UI uses for the CalDAV dialog instead of hardcoding ids.","After changing provider presets on the server, restart the backend and reload the client so both sides agree on the preset list.","Verify CalDAV is actually enabled (calendar.caldav.enabled) first; if it is disabled you will instead get caldav_disabled."],"exampleFix":"// before\ndiscoverCalDAVAccount({ input: { providerPresetId: 'Fastmail', username, password } });\n\n// after — use the exact id from config.calendar.caldav.providers\ndiscoverCalDAVAccount({ input: { providerPresetId: 'fastmail', username, password } });","handlingStrategy":"validation","validationCode":"const presets = await calendarClient.getCalDAVPresets(); // from server config\nif (!presets.some(p => p.id === input.providerPresetId)) {\n  throw new Error(`Unknown CalDAV preset '${input.providerPresetId}'. Available: ${presets.map(p => p.id).join(', ')}`);\n}","typeGuard":"const isKnownPreset = (id: string, presets: { id: string }[]) =>\n  presets.some(p => p.id === id);","tryCatchPattern":"try {\n  await discoverCalDAVAccount({ input: { providerPresetId, username, password } });\n} catch (e) {\n  if (e?.extensions?.code === 'caldav_provider_not_found') {\n    await refreshPresetList(); // re-sync ids from server, re-prompt user\n  } else throw e;\n}","preventionTips":["Always populate the preset picker from the live server config, never from hardcoded lists.","Treat preset ids as opaque server-owned identifiers — never transform or guess them.","Re-fetch presets after server config changes or upgrades."],"tags":["caldav","calendar","graphql","config","provider-preset"],"backgroundTag":"invalid-config-value","analyzedSha":"591f874dad30887a80143a061a44bd3ca7ee3299","analyzedAt":"2026-08-18T21:16:52.546Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}