{"record":{"id":"4091c63e9bac5e33","repo":"Mintplex-Labs/anything-llm","slug":"scheme-not-supported-connectionstringobject-sch","errorCode":null,"errorMessage":"Scheme not supported: ${connectionStringObject.scheme}","messagePattern":"Scheme not supported: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/utils/agents/aibitat/plugins/sql-agent/SQLConnectors/utils.js","lineNumber":43,"sourceCode":"      (options && options.scheme) || ConnectionStringParser.DEFAULT_SCHEME;\n  }\n\n  /**\n   * Takes a connection string object and returns a URI string of the form:\n   *\n   * scheme://[username[:password]@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[endpoint]][?options]\n   * @param {Object} connectionStringObject The object that describes connection string parameters\n   */\n  format(connectionStringObject) {\n    if (!connectionStringObject) {\n      return this.scheme + \"://localhost\";\n    }\n    if (\n      this.scheme &&\n      connectionStringObject.scheme &&\n      this.scheme !== connectionStringObject.scheme\n    ) {\n      throw new Error(`Scheme not supported: ${connectionStringObject.scheme}`);\n    }\n\n    let uri =\n      (this.scheme ||\n        connectionStringObject.scheme ||\n        ConnectionStringParser.DEFAULT_SCHEME) + \"://\";\n\n    if (connectionStringObject.username) {\n      uri += encodeURIComponent(connectionStringObject.username);\n      // Allow empty passwords\n      if (connectionStringObject.password) {\n        uri += \":\" + encodeURIComponent(connectionStringObject.password);\n      }\n      uri += \"@\";\n    }\n    uri += this._formatAddress(connectionStringObject);\n    // Only put a slash when there is an endpoint\n    if (connectionStringObject.endpoint) {","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/3aec848f2885144aa8f1e53b9731a04310d5d558/server/utils/agents/aibitat/plugins/sql-agent/SQLConnectors/utils.js#L25-L61","documentation":"Thrown by ConnectionStringParser.format when the parser was constructed with a fixed scheme (e.g. 'mysql' or 'postgresql') but the connection-string object passed in carries a different non-empty scheme. format() serializes an object back into a URI and refuses to emit a scheme it was not built for, rather than silently producing a cross-engine connection string.","triggerScenarios":"Constructing a parser for one engine (new ConnectionStringParser({ scheme: 'mysql' })) and calling format({ scheme: 'postgres', ... }); mixing a parsed PostgreSQL URI's object into a MySQL formatter; stored config edited so scheme no longer matches the connector that formats it.","commonSituations":"Copy-pasting connection objects between connector configs when switching databases; scheme aliases ('postgres' vs 'postgresql') passed through from user input into format().","solutions":["Make the object's scheme match the parser's scheme exactly, or omit scheme from the object so the parser's own scheme is used.","If the object genuinely belongs to another engine, use a parser constructed with that engine's scheme.","Normalize aliases before formatting: 'postgres'->'postgresql', 'mssql'/'sqlserver'->'sql-server' per the connector in use."],"exampleFix":"// before\nconst parser = new ConnectionStringParser({ scheme: \"mysql\" });\nparser.format({ scheme: \"postgresql\", hosts: [...] });  // throws\n\n// after\nparser.format({ hosts: [...] });  // parser's own scheme 'mysql' is used","handlingStrategy":"validation","validationCode":"function formatSafely(parser, obj) {\n  const o = { ...obj };\n  if (o.scheme && o.scheme !== parser.scheme) {\n    delete o.scheme; // let the parser's own scheme win, or reject explicitly:\n    // throw new Error(`scheme '${o.scheme}' does not match connector '${parser.scheme}'`);\n  }\n  return parser.format(o);\n}","typeGuard":"/** @returns {boolean} */\nfunction schemeMatches(parser, obj) {\n  return !obj?.scheme || !parser?.scheme || parser.scheme === obj.scheme;\n}","tryCatchPattern":"try {\n  const uri = parser.format(connectionStringObject);\n} catch (e) {\n  if (e.message.startsWith(\"Scheme not supported:\")) {\n    // either drop obj.scheme or route the object to a parser built for that scheme\n  } else throw e;\n}","preventionTips":["Construct one ConnectionStringParser per engine and never share objects across them.","Store engine and connection string as an atomic pair in config.","Normalize scheme aliases before formatting."],"tags":["sql-agent","connection-string","scheme","config"],"backgroundTag":"connection-string-scheme-mismatch","analyzedSha":"3aec848f2885144aa8f1e53b9731a04310d5d558","analyzedAt":"2026-08-18T10:02:21.017Z","contentChangedAt":"2026-08-18T10:02:21.017Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}