{"record":{"id":"1a38d8c24a3a4183","repo":"lfnovo/open-notebook","slug":"failed-to-list-credentials-for-provider","errorCode":null,"errorMessage":"Failed to list credentials for provider","messagePattern":"Failed to list credentials for provider","errorType":"http","errorClass":"HTTPException","httpStatus":500,"severity":"error","filePath":"api/routers/credentials.py","lineNumber":158,"sourceCode":"\n\n@router.get(\"/by-provider/{provider}\", response_model=List[CredentialResponse])\nasync def list_credentials_by_provider(provider: str):\n    \"\"\"List all credentials for a specific provider.\"\"\"\n    try:\n        credentials = await Credential.get_by_provider(provider.lower())\n        result = []\n        for cred in credentials:\n            models = await cred.get_linked_models()\n            result.append(credential_to_response(cred, len(models)))\n        return result\n    except HTTPException:\n        raise\n    except OpenNotebookError:\n        raise\n    except Exception as e:\n        logger.error(f\"Error listing credentials for {provider}: {e}\")\n        raise HTTPException(status_code=500, detail=\"Failed to list credentials for provider\")\n\n\n@router.post(\"\", response_model=CredentialResponse, status_code=201)\nasync def create_credential(request: CreateCredentialRequest):\n    \"\"\"Create a new credential.\"\"\"\n    try:\n        require_encryption_key()\n    except ValueError as e:\n        raise _handle_value_error(e)\n\n    # Validate all URL fields\n    for url_field in [\n        request.base_url, request.endpoint, request.endpoint_llm,\n        request.endpoint_embedding, request.endpoint_stt, request.endpoint_tts,\n    ]:\n        if url_field:\n            try:\n                await validate_url(url_field, request.provider)","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/lfnovo/open-notebook/blob/a7de90d38aaf18ee85fd661854d35c11e44613e2/api/routers/credentials.py#L140-L176","documentation":"Catch-all 500 from GET /api/credentials/by-provider/{provider} when fetching credentials scoped to one provider fails unexpectedly. Same failure class as the list endpoint but narrowed by the provider filter.","triggerScenarios":"Calling GET /api/credentials/by-provider/openai (or any provider slug) while the DB is unavailable, or when the query for that provider's records hits an undecryptable secret or malformed record.","commonSituations":"Provider string with unexpected casing/characters causing a query error, database restart mid-request, or encryption key mismatch on stored provider credentials.","solutions":["Check the log line 'Error listing credentials for <provider>: ...' for the root cause","Verify the provider slug matches known values (openai, anthropic, etc.) and the DB is reachable","Validate OPEN_NOTEBOOK_ENCRYPTION_KEY if decryption of stored secrets is implicated","Retry after the database is healthy"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"const KNOWN_PROVIDERS = ['openai', 'anthropic', 'gemini', 'azure', 'openrouter'];\nif (!KNOWN_PROVIDERS.includes(provider.toLowerCase())) {\n  // avoid the call entirely for unknown slugs\n  return [];\n}","typeGuard":null,"tryCatchPattern":"try {\n  const creds = await api.listByProvider(provider);\n} catch (e) {\n  if (e.status === 500) return []; // degrade to empty list with a refresh affordance\n  throw e;\n}","preventionTips":["Validate provider slugs against the known set before requesting","Reuse the general list endpoint and filter client-side as a fallback"],"tags":["credentials","provider","http-500"],"backgroundTag":"http-500-fallback","analyzedSha":"a7de90d38aaf18ee85fd661854d35c11e44613e2","analyzedAt":"2026-08-27T02:39:58.166Z","schemaVersion":2},"datasetVersion":"2026-08-27T03:17:27.898Z"}