lfnovo/open-notebook · error · HTTPException

Failed to list credentials

Error message

Failed to list credentials

What it means

Catch-all 500 from the credential list endpoint (GET /api/credentials). It fires when listing credentials raises an exception that is neither HTTPException nor an OpenNotebookError — typically a database-level failure during the await db query.

Source

Thrown at api/routers/credentials.py:139

        if provider:
            credentials = await Credential.get_by_provider(provider)
        else:
            credentials = await Credential.get_all(order_by="provider, created")

        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: {e}")
        raise HTTPException(status_code=500, detail="Failed to list credentials")


@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}")

View on GitHub (pinned to a7de90d38a)

Solutions

  1. Read the API log line 'Error listing credentials: ...' to identify the underlying exception
  2. Ensure the database tier is up: make database, then make status
  3. If a specific record fails to deserialize, inspect/remove the offending credential record via a DB query
  4. Restart the API so automatic schema migrations run, then retry
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const creds = await api.listCredentials();
} catch (e) {
  if (e.status === 500) { showEmptyStateWithRetry(); return; }
  throw e;
}

Prevention

When it happens

Trigger: GET /api/credentials when SurrealDB is down or returns an unexpected error, or when a stored credential row cannot be deserialized into the Credential domain model (corrupt/legacy record).

Common situations: SurrealDB container stopped or restarting, records written by an older schema version, or permissions/connection config mismatch after an env change.

Related errors


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