{"record":{"id":"67e1b8fb4e5bd919","repo":"ToolJet/ToolJet","slug":"url-missing","errorCode":null,"errorMessage":"URL missing","messagePattern":"URL missing","errorType":"validation","errorClass":"QueryError","httpStatus":null,"severity":"error","filePath":"marketplace/plugins/qdrant/lib/index.ts","lineNumber":81,"sourceCode":"    };\n  }\n  async testConnection(sourceOptions: SourceOptions): Promise<ConnectionTestResult> {\n    const qdrant = await this.getConnection(sourceOptions);\n\n    try {\n      await qdrant.getCollections();\n      return { status: 'ok' };\n    } catch (error) {\n      console.error('Connection could not be established:', error.message);\n      throw new QueryError('Connection could not be established', error?.message, {});\n    }\n  }\n\n  async getConnection(sourceOptions: SourceOptions): Promise<QdrantClient> {\n    const { apiKey, url } = sourceOptions;\n\n    if (!url) {\n      throw new QueryError('URL missing', 'No Qdrant URL provided in source options', {});\n    }\n\n    return new QdrantClient({\n      url,\n      apiKey,\n    });\n  }\n\n  private parseJSON(json?: string): object {\n    if (!json) return {};\n\n    return JSON.parse(json);\n  }\n}\n","sourceCodeStart":63,"sourceCodeEnd":96,"githubUrl":"https://github.com/ToolJet/ToolJet/blob/20602a8e101f2e59686c9afde0d1402aac2c8871/marketplace/plugins/qdrant/lib/index.ts#L63-L96","documentation":"Thrown by Qdrant getConnection() as a QueryError when sourceOptions.url is falsy. The QdrantClient constructor requires a URL, so the plugin refuses to construct one without it. This fires before any network call and before testConnection's getCollections attempt.","triggerScenarios":"getConnection() destructures { apiKey, url } from sourceOptions and finds url undefined/empty. The datasource was saved without a URL, or the URL field key sent to the backend does not match 'url'.","commonSituations":"Datasource URL field left blank; field key mismatch after a schema change; environment/migration issue where sourceOptions was not hydrated; copy of a datasource config that dropped the URL.","solutions":["Set the Qdrant URL in the datasource configuration (e.g. http://localhost:6333 or https://<cluster>.cloud.qdrant.io) and save.","Confirm the option key is exactly 'url' on the backend side.","If calling programmatically, ensure sourceOptions contains { url: string, apiKey?: string }."],"exampleFix":"// before\nconst sourceOptions = { apiKey: 'xxx' }; // url missing\n\n// after\nconst sourceOptions = { url: 'http://localhost:6333', apiKey: 'xxx' };","handlingStrategy":"validation","validationCode":"function assertQdrantSource(opts: { url?: string; apiKey?: string }) {\n  if (!opts?.url || !opts.url.trim()) throw new Error('Qdrant url is required in source options.');\n}","typeGuard":"const hasQdrantUrl = (o: unknown): o is { url: string; apiKey?: string } =>\n  typeof o === 'object' && o !== null && typeof (o as any).url === 'string' && (o as any).url.trim() !== '';","tryCatchPattern":"try { return await plugin.getConnection(sourceOptions); }\ncatch (e) { if (/URL missing|No Qdrant URL/.test(e?.message ?? '')) { /* prompt to set url */ } throw e; }","preventionTips":["Make the Qdrant URL a required datasource field so it cannot be saved empty.","Trim and validate the URL on save.","Run 'Test connection' right after configuring to catch missing URL early."],"tags":["qdrant","validation","configuration","required-field","typescript"],"backgroundTag":null,"analyzedSha":"20602a8e101f2e59686c9afde0d1402aac2c8871","analyzedAt":"2026-08-13T05:58:54.221Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}