{"record":{"id":"126334aa739a473c","repo":"can1357/oh-my-pi","slug":"smithery-api-key-not-found-after-login","errorCode":null,"errorMessage":"Smithery API key not found after login.","messagePattern":"Smithery API key not found after login\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/modes/controllers/mcp-command-controller.ts","lineNumber":2498,"sourceCode":"\t\treturn undefined;\n\t}\n\n\t#toSmitheryAuthReason(status: number): string {\n\t\treturn status === 429 ? \"rate limited by Smithery\" : \"forbidden/unauthorized with Smithery\";\n\t}\n\n\tasync #requireSmitheryApiKey(reason: string): Promise<string> {\n\t\tlet apiKey = await getSmitheryApiKey();\n\t\tif (apiKey) return apiKey;\n\n\t\tconst loggedIn = await this.#promptSmitheryLogin(reason);\n\t\tif (!loggedIn) {\n\t\t\tthrow new Error(\"Smithery login cancelled. Run /mcp smithery-login, then retry /mcp smithery-search.\");\n\t\t}\n\n\t\tapiKey = await getSmitheryApiKey();\n\t\tif (!apiKey) {\n\t\t\tthrow new Error(\"Smithery API key not found after login.\");\n\t\t}\n\t\treturn apiKey;\n\t}\n\n\tasync #runSmitheryOperationWithAuthRetry<T>(operation: (apiKey: string) => Promise<T>, reason: string): Promise<T> {\n\t\tconst apiKey = await this.#requireSmitheryApiKey(reason);\n\t\ttry {\n\t\t\treturn await operation(apiKey);\n\t\t} catch (error) {\n\t\t\tconst status = this.#getSmitheryErrorStatus(error);\n\t\t\tif (status === undefined || ![401, 403, 429].includes(status)) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tconst loggedIn = await this.#promptSmitheryLogin(this.#toSmitheryAuthReason(status));\n\t\t\tif (!loggedIn) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tconst retryApiKey = await this.#requireSmitheryApiKey(reason);","sourceCodeStart":2480,"sourceCodeEnd":2516,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/modes/controllers/mcp-command-controller.ts#L2480-L2516","documentation":"Thrown by #requireSmitheryApiKey when the login flow reported success (#promptSmitheryLogin returned true) but a subsequent getSmitheryApiKey() still returns nothing — i.e. the key was not actually persisted despite the login reporting completion. This indicates an inconsistency between the login result and credential storage.","triggerScenarios":"Browser login flow completes (#handleSmitheryBrowserLogin validated and saved the key) or the API-key path returns true, yet getSmitheryApiKey() finds no stored key afterwards — e.g. a storage write failure silently swallowed, a race where another claim overwrote/cleared the key, or the storage file became unreadable between save and read.","commonSituations":"Permission problems on the config/credentials file preventing the save; concurrent OMP sessions racing on the key store; a keyring/OS credential store failure that the save path did not surface; disk-full conditions.","solutions":["Re-run /mcp smithery-login; if it succeeds again and the error repeats, the key save is failing — check write permissions on your OMP config/credentials location.","Verify no second OMP instance is running that might race the key store; close others and retry.","As a workaround, check for errors in the OMP log (~/.omp/logs/) around the save and fix the underlying storage issue (permissions, disk space).","If storage remains broken, report the persistence failure — the login path should have surfaced the save error instead of reporting success."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const key = await getSmitheryApiKey();\nif (!key) {\n  // storage read returned nothing — check the credentials file is readable before blaming the login\n  console.error(\"Smithery key missing from store; check config dir permissions/disk space.\");\n}","typeGuard":"function isPostLoginKeyMissing(err: unknown): err is Error {\n  return err instanceof Error && err.message === \"Smithery API key not found after login.\";\n}","tryCatchPattern":"try {\n  await smitherySearch(query);\n} catch (err) {\n  if (isPostLoginKeyMissing(err)) {\n    // login 'succeeded' but persistence failed: re-login and watch for save errors\n    await smitheryLogin();\n  } else throw err;\n}","preventionTips":["Keep the OMP config/credentials location writable (check permissions and free disk space).","Avoid running multiple OMP instances concurrently during login to prevent key-store races.","After a successful login, verify the key persisted (the status message 'Smithery API key saved.') before issuing dependent commands.","Inspect ~/.omp/logs/ for silent write failures if the error recurs."],"tags":["smithery","api-key","storage","persistence"],"backgroundTag":"credential-save-failed","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}