lfnovo/open-notebook · error · HTTPException

Failed to list credentials for provider

Error message

Failed to list credentials for provider

What it means

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.

Solutions

  1. Check the log line 'Error listing credentials for <provider>: ...' for the root cause
  2. Verify the provider slug matches known values (openai, anthropic, etc.) and the DB is reachable
  3. Validate OPEN_NOTEBOOK_ENCRYPTION_KEY if decryption of stored secrets is implicated
  4. Retry after the database is healthy
Defensive patterns

Strategy: try-catch

Validate before calling

const KNOWN_PROVIDERS = ['openai', 'anthropic', 'gemini', 'azure', 'openrouter'];
if (!KNOWN_PROVIDERS.includes(provider.toLowerCase())) {
  // avoid the call entirely for unknown slugs
  return [];
}

Try / catch

try {
  const creds = await api.listByProvider(provider);
} catch (e) {
  if (e.status === 500) return []; // degrade to empty list with a refresh affordance
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: Provider string with unexpected casing/characters causing a query error, database restart mid-request, or encryption key mismatch on stored provider credentials.

Related errors


AI-assisted analysis of lfnovo/open-notebook@a7de90d38a (2026-08-27). Data as JSON: /api/errors/1a38d8c24a3a4183. Report an issue: GitHub.

Appendix: source

Thrown at api/routers/credentials.py:158


@router.get("/by-provider/{provider}", response_model=List[CredentialResponse])
async def list_credentials_by_provider(provider: str):
    """List all credentials for a specific provider."""
    try:
        credentials = await Credential.get_by_provider(provider.lower())
        result = []
        for cred in credentials:
            models = await cred.get_linked_models()
            result.append(credential_to_response(cred, len(models)))
        return result
    except HTTPException:
        raise
    except OpenNotebookError:
        raise
    except Exception as e:
        logger.error(f"Error listing credentials for {provider}: {e}")
        raise HTTPException(status_code=500, detail="Failed to list credentials for provider")


@router.post("", response_model=CredentialResponse, status_code=201)
async def create_credential(request: CreateCredentialRequest):
    """Create a new credential."""
    try:
        require_encryption_key()
    except ValueError as e:
        raise _handle_value_error(e)

    # Validate all URL fields
    for url_field in [
        request.base_url, request.endpoint, request.endpoint_llm,
        request.endpoint_embedding, request.endpoint_stt, request.endpoint_tts,
    ]:
        if url_field:
            try:
                await validate_url(url_field, request.provider)

View on GitHub (pinned to a7de90d38a)