{"record":{"id":"e082031c3ff3c1ec","repo":"continuedev/continue","slug":"profile-profileid-not-found","errorCode":null,"errorMessage":"Profile ${profileId} not found","messagePattern":"Profile (.+?) not found","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"core/config/ConfigHandler.ts","lineNumber":218,"sourceCode":"  // Ide settings change: refresh session and cascade refresh from the top\n  async updateIdeSettings(ideSettings: IdeSettings) {\n    this.abortCascade();\n    await this.cascadeInit(\"IDE settings update\");\n  }\n\n  // Profile id: check id validity, save selection, switch and reload\n  async setSelectedProfileId(profileId: string) {\n    if (\n      this.currentProfile &&\n      profileId === this.currentProfile.profileDescription.id\n    ) {\n      return;\n    }\n    const profile = this.profiles.find(\n      (profile) => profile.profileDescription.id === profileId,\n    );\n    if (!profile) {\n      throw new Error(`Profile ${profileId} not found`);\n    }\n\n    const workspaceId = await this.getWorkspaceId();\n    const selectedProfiles =\n      this.globalContext.get(\"lastSelectedProfileForWorkspace\") ?? {};\n    this.globalContext.update(\"lastSelectedProfileForWorkspace\", {\n      ...selectedProfiles,\n      [workspaceId]: profileId,\n    });\n\n    this.currentProfile = profile;\n    await this.reloadConfig(\"Selected profile changed\");\n  }\n\n  // Bottom level of cascade: refresh the current profile\n  // IMPORTANT - must always refresh when switching profiles\n  // Because of e.g. MCP singleton and docs service using things from config\n  // Could improve this","sourceCodeStart":200,"sourceCodeEnd":236,"githubUrl":"https://github.com/continuedev/continue/blob/5522c6f44ca0ac3528b37244818fbfa39b5af470/core/config/ConfigHandler.ts#L200-L236","documentation":"Defensive type check on the keyFile config option: when a truthy keyFile is supplied it must be a string filesystem path, because it is forwarded directly to google-auth-library's GoogleAuth({ keyFile }). Any non-string truthy value (object, buffer, number) is rejected.","triggerScenarios":"Passing keyFile as a parsed JSON object (same shape you'd give keyJson), a Buffer, or a URL instead of a local path string.","commonSituations":"Developer confuses keyFile (path) with keyJson (contents) and passes the parsed credentials object to keyFile; or passes a remote/GS URL expecting the library to fetch it.","solutions":["Pass a filesystem path string: keyFile: '/secrets/sa.json'","If you already have the key contents/object, use keyJson instead","For remote secrets, download to a temp file or read it into keyJson"],"exampleFix":"// before\nnew VertexAIApi({ keyFile: JSON.parse(fs.readFileSync('sa.json','utf8')) });\n\n// after\nnew VertexAIApi({ keyFile: 'sa.json' });\n// or\nnew VertexAIApi({ keyJson: fs.readFileSync('sa.json','utf8') });","handlingStrategy":"validation","validationCode":"if (cfg.keyFile !== undefined && typeof cfg.keyFile !== 'string') throw new TypeError('keyFile must be a path string');","typeGuard":"const isKeyFileConfig = (c: { keyFile?: unknown }): c is { keyFile: string } => typeof c.keyFile === 'string';","tryCatchPattern":null,"preventionTips":["Remember keyFile = path, keyJson = contents","Type your config objects instead of using any"],"tags":["vertexai","config","type-validation"],"backgroundTag":"invalid-config-value","analyzedSha":"5522c6f44ca0ac3528b37244818fbfa39b5af470","analyzedAt":"2026-08-27T11:28:54.683Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}