lfnovo/open-notebook · error · HTTPException

Credential not found

Error message

Credential not found

What it means

404 returned by GET /api/credentials/{credential_id}. Note this handler catches ALL non-HTTP, non-OpenNotebook exceptions as 404 — so it means either the credential genuinely does not exist, or a lookup blew up unexpectedly.

Source

Thrown at api/routers/credentials.py:223

    except Exception as e:
        logger.error(f"Error creating credential: {e}")
        raise HTTPException(status_code=500, detail="Failed to create credential")


@router.get("/{credential_id}", response_model=CredentialResponse)
async def get_credential(credential_id: str):
    """Get a specific credential by ID. Never returns api_key."""
    try:
        cred = await Credential.get(credential_id)
        models = await cred.get_linked_models()
        return credential_to_response(cred, len(models))
    except HTTPException:
        raise
    except OpenNotebookError:
        raise
    except Exception as e:
        logger.error(f"Error fetching credential {credential_id}: {e}")
        raise HTTPException(status_code=404, detail="Credential not found")


@router.put("/{credential_id}", response_model=CredentialResponse)
async def update_credential(credential_id: str, request: UpdateCredentialRequest):
    """Update an existing credential."""
    try:
        require_encryption_key()
    except ValueError as e:
        raise _handle_value_error(e)

    # Validate all URL fields being updated
    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, "update")

View on GitHub (pinned to a7de90d38a)

Solutions

  1. Verify the ID exists by listing credentials (GET /api/credentials) and copying the exact id
  2. If records vanished, check whether the database was reset or pointed at a different namespace/database in config
  3. Check logs for 'Error fetching credential <id>: ...' — an exception there means the 404 is masking a real error
  4. Refresh the client's cached credential list before retrying
Defensive patterns

Strategy: try-catch

Validate before calling

const creds = await api.listCredentials();
const exists = creds.some(c => c.id === credentialId);
if (!exists) refreshCredentialList();

Try / catch

try {
  const cred = await api.getCredential(credentialId);
} catch (e) {
  if (e.status === 404) { removeFromLocalCache(credentialId); showNotFound(); return; }
  throw e;
}

Prevention

When it happens

Trigger: Fetching a credential with a stale/wrong ID (e.g. after it was deleted or after a DB reset wiped records), or an unexpected exception during fetch that the blanket handler maps to 404.

Common situations: Frontend holding a cached credential ID from a previous session, DB reinitialized without preserving records, or ID typo/manipulation in the URL.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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