Keep Exception Messages

This reference guide documents all exception codes that may be returned by the acre Access Control API. Understanding these exceptions helps you build robust error handling into your integrations.


Quick Navigation

Category Description
Authentication Errors Login, password, and user account issues
Permission Errors Access control and authorization failures
Object Errors CRUD operation failures
Validation Errors Data format and constraint violations
Hardware Errors Controller and peripheral issues
Instance Errors Multi-tenant and instance management issues
Card Errors Card assignment and credential issues
Query Errors Search and aggregate operation failures

Handling Exceptions in Code

Important: The acre API wrapper throws FailedOutcomeException instead of KeepException. The underlying REST API returns KeepException error codes, but the C# wrapper wraps these in FailedOutcomeException. Always handle null returns and check exception details.

using Flurl.Http;
using Feenics.Keep.WebApi.Wrapper;

public async Task<PersonInfo?> AddPersonSafelyAsync(InstanceInfo instance, PersonInfo newPerson)
{
    try
    {
        // Wrapper returns the created person or throws on error
        var person = await client.AddPersonAsync(instance, newPerson);
        
        // Important: Some wrapper methods may return null instead of throwing
        if (person == null)
        {
            Console.WriteLine("Person creation returned null - check permissions or instance state");
            return null;
        }
        
        return person;
    }
    catch (FailedOutcomeException ex) when (ex.HttpStatus == System.Net.HttpStatusCode.Conflict)
    {
        // Duplicate name or similar conflict
        // ResponseString contains the full KeepException details
        Console.WriteLine($"Conflict creating person: {ex.ResponseString}");
        return null;
    }
    catch (FailedOutcomeException ex) when (ex.HttpStatus == System.Net.HttpStatusCode.Forbidden)
    {
        // Permission denied - ResponseString provides specific permission error details
        Console.WriteLine($"Permission denied: {ex.ResponseString}");
        return null;
    }
    catch (FailedOutcomeException ex) when (ex.HttpStatus == System.Net.HttpStatusCode.BadRequest)
    {
        // Validation error - ResponseString includes which validation rule failed
        Console.WriteLine($"Validation failed: {ex.ResponseString}");
        return null;
    }
    catch (FailedOutcomeException ex)
    {
        // Other API errors (500, etc.) - always log ResponseString for troubleshooting
        Console.WriteLine($"API error: HTTP {ex.HttpStatus} - {ex.ResponseString}");
        return null;
    }
    catch (FlurlHttpException ex)
    {
        // Network-level errors (connection timeout, DNS failure, etc.)
        Console.WriteLine($"Network error: {ex.Message}");
        return null;
    }
    catch (Exception ex)
    {
        // Unexpected errors - log and rethrow
        Console.WriteLine($"Unexpected error: {ex.Message}");
        throw;
    }
}

Direct REST API Example (KeepException)

When calling the REST API directly (not using the C# wrapper), the API returns JSON error responses with KeepException details:

// Direct HTTP call - returns KeepException details in response body
using System.Net.Http;
using System.Text.Json;

var response = await httpClient.PostAsJsonAsync($"{apiUrl}/api/f/{instanceKey}/Person", newPerson);

if (!response.IsSuccessStatusCode)
{
    var errorJson = await response.Content.ReadAsStringAsync();
    var error = JsonDocument.Parse(errorJson);
    
    // Access error details from JSON response
    var exceptionCode = error.RootElement.GetProperty("Error").GetString();
    var message = error.RootElement.GetProperty("Message").GetString();
    
    switch (exceptionCode)
    {
        case "CannotInsertDuplicateName":
            Console.WriteLine($"A person with this name already exists: {message}");
            break;
        case "PermissionsError":
            Console.WriteLine($"Permission denied: {message}");
            break;
        default:
            Console.WriteLine($"Error: {exceptionCode} - {message}");
            break;
    }
}

Python Example (REST API)

import requests

response = requests.post(f"{api_url}/api/f/{instance_key}/Person", 
                         json=person_data, headers=headers)

if response.status_code != 200:
    error = response.json()
    error_code = error.get('Error', 'Unknown')
    
    if error_code == 'CannotInsertDuplicateName':
        print(f"Duplicate name: {person_data['CommonName']}")
    elif error_code == 'PermissionsError':
        print("Permission denied")
    else:
        print(f"Error: {error_code} - {error.get('Message')}")

Authentication Errors

Issues related to user login, passwords, and account status.

Code Description Resolution
UserDoesNotExist The specified username was not found Verify username spelling and case
IncorrectPassword The password provided is wrong Verify password; check for caps lock
NewPasswordRequired User must set a new password before continuing Prompt user for password change
UserIsDisabled The user account has been disabled Contact system administrator
UserIsLockedOut Account locked due to failed login attempts Wait for lockout period or contact admin
PasswordExpired The password has exceeded its age limit User must change password
UserCannotChangePassword Policy prevents this user from changing password Contact system administrator
CannnotChangePasswordOnLogin Password change not allowed during login Use separate password change flow
PasswordDoesNotMeetMinimumLength New password is too short Use a longer password
PasswordDoesNotMeetComplexityRule New password doesn’t meet complexity requirements Include uppercase, lowercase, numbers, symbols
PasswordRecentlyUsed New password was used previously Choose a different password
MustSupplyTwoFactorPassword Two-factor authentication required Provide 2FA code
IncorrectTwoFactorPassword The 2FA code is incorrect Verify 2FA code; may need new code
CurrentUserNotSet No authenticated user context Ensure proper authentication

Permission Errors

Authorization and access control failures.

Code Description Resolution
PermissionsError Generic permission denied Check user’s Operation Rights
UnableToMoveToFolderMissingPermissions Cannot move object to target folder Grant folder permissions or choose different folder
UnableToTakeOwnershipMissingPermissions Cannot take ownership of object Grant ownership permissions
UnableToSearchHiddenObjectsMissingPermissions Cannot search hidden objects Grant hidden object search permission
MissingSystemInPermissionsTest Permission check missing system context Verify permission configuration

Object Errors

Failures during create, read, update, or delete operations.

Code Description Resolution
ObjectNotFound The requested object doesn’t exist Verify object Key; may have been deleted
UnableToUpdateObject Update operation failed Check object state and permissions
CannotUpdateMissingObjectId Object ID not provided for update Include object ID/Key in update request
MissingFolder The specified folder doesn’t exist Create folder or use existing one
IncorrectUsageKeyProvidedOnInsert Wrong key format used during creation Use correct key format for object type
CannotInsertDuplicateName Object with same name exists Use unique name or update existing object
CannotInsertDuplicateUser Username already exists Choose different username
GroupDoesNotExist The specified group was not found Verify group Key
ArgumentNotAnObjectId Invalid object ID format Use valid MongoDB ObjectId format
ValueCannotBeNull Required field is null Provide required field value
UsernameCannotBeNull Username field is required Provide username
CannotChangeFolder Object cannot be moved to different folder Folder assignment is fixed for this object type
CannotRemoveMultipleLinkedObjects Cannot bulk remove linked objects Remove links individually
NotModified Update contained no changes Object is already in desired state

Validation Errors

Data format and constraint violations.

Code Description Resolution
ValidationError Generic validation failure Check error message for specific field
BadQueryFormat MongoDB query syntax error Verify query JSON format
InvalidOperation Operation not valid in current context Check object state before operation
InvalidAggregateOperation Aggregate pipeline error Verify aggregate stage syntax
InvalidAggregateTimeout Aggregate operation timed out Simplify query or use streaming
QueryTooLarge Query results exceed maximum size Use pagination or streaming

Hardware Errors

Controller, downstream, and peripheral device issues.

Code Description Resolution
MaxDownstreamExceeded Controller downstream limit reached Use different controller or remove unused downstreams
MaxDownstreamPeripheralsExceeded Downstream peripheral limit reached Balance peripherals across downstreams
MaxPeripheralsExceeded Maximum peripherals exceeded Redistribute across controllers
PeripheralMissingDownstreamLink Peripheral not linked to downstream Add ObjectLink to downstream
MissingControllerLink Object missing controller reference Link object to controller
CannotUpdateControllerPackage Controller firmware update failed Check controller connectivity
CannotSetDestinationDispatchSettings Invalid dispatch configuration Verify dispatch settings format
CannotSetDestinationReaderSettings Invalid reader settings Verify reader configuration
CannotChangeControllerType Controller type cannot be changed Create new controller of desired type
CannotChangeControllerToSameType Already the specified type No action needed
CannotChangeControllerNoCompatibleType No compatible conversion available Create new controller instead
IncorrectAddressingModeForInterface Interface addressing mode mismatch Configure correct addressing mode
InputScannerReportingPrioritiesIncorrect Invalid input scanner configuration Fix reporting priorities
ServiceContainerNotFoundByMacAddress Controller not found by MAC Verify MAC address; check controller registration
ServiceContainerHasAssociatedUser Controller already has user association Remove existing user association first
ServiceContainerNonceIsNull Controller security nonce missing Re-register controller
DuplicateServiceContainerNonce Duplicate controller security token Re-register controller with new nonce
DuplicateMacAddress MAC address already registered Verify MAC address uniqueness
MustDisableIfMissingMacAddress Controller without MAC must be disabled Add MAC address or disable controller
ReaderIsNotVersioned Reader doesn’t support versioning Use compatible reader
ReaderIsNotSchlage Operation requires Schlage reader Use Schlage reader
DuplicateEngageDevice Engage device already registered Verify device ID uniqueness
DuplicateElevatorUserSettingForController Duplicate elevator configuration Remove duplicate settings

Instance Errors

Multi-tenant and instance management issues.

Code Description Resolution
InstanceDoesNotExist The specified instance was not found Verify instance Key; check permissions
MissingInstance No instance context provided Include instance in request
MissingInInstanceLink Object missing instance link Add ObjectLink to instance
MissingInstanceScopeLink Object missing instance scope Set instance scope
MissingCurrentInstance No current instance set Call GetCurrentInstance first
CurrentInstanceNotRoot Operation requires root instance Switch to root instance
UnableToScopeObjectToInstance Cannot scope object to instance Check instance hierarchy and permissions
CannotMoveInstanceToItself Cannot move instance to itself Select different target instance
CannotMoveInstanceToNonVarInstance Target must be VAR instance Move to VAR instance only
CannotMoveSharedInstance Shared instances cannot be moved Convert from shared first
CannotMoveInstanceAlreadyInTargetInstance Already in target instance No action needed
CannotMoveEnterpriseToEnterprise Cannot move enterprise to enterprise Use different target type
CannotObliterateRootInstance Cannot delete root instance Cannot perform this operation
DuplicateInstanceName Instance name already exists Use unique instance name
InvalidInstanceName Instance name is invalid Use valid characters in name
NotVarInstance Operation requires VAR instance Switch to VAR instance
InstanceIsDisabled Instance has been disabled Enable instance or contact admin

Card Errors

Card assignment and credential management issues.

Code Description Resolution
CardIsAlreadyAssigned Card number already in use Use different card number or unassign existing
DuplicateCardNumberInBatch Same card number appears twice in batch Remove duplicate from batch
DuplicateCardNumberInPerson Person already has this card Card already assigned to this person
CannotChangeEncodedCardNumber Encoded card number is immutable Create new card assignment
CannotChangeCardHexValue Card hex value cannot be modified Create new card assignment
CardHexValueNotPadded Card hex value needs padding Pad hex value to correct length
CardHexValueNotValid Invalid card hex format Use valid hexadecimal format
CannotDeleteCardAssignment Card assignment cannot be deleted Check card status and linked events
DuplicatePinCode PIN code already in use Use different PIN code
MissingPersonForUser User has no linked person record Link user to person record
MultipleUsersForPerson Person has multiple user accounts Remove duplicate user accounts

Query Errors

Search and aggregate operation failures.

Code Description Resolution
BadQueryFormat MongoDB query has syntax errors Validate JSON query syntax
QueryTooLarge Query results exceed size limits Use pagination, streaming, or narrower criteria
InvalidAggregateOperation Aggregate pipeline stage is invalid Check aggregate stage syntax
InvalidAggregateTimeout Aggregate operation exceeded timeout Simplify pipeline or use background processing

System Errors

General system and infrastructure issues.

Code Description Resolution
MongoInitializationFailure Database initialization failed Contact support; check database connectivity
UnexpectedGeneralException Unexpected error occurred Check logs; contact support if persistent
UnableToFindAndUpdateIdentityCounter ID generation failed Contact support
CannotChangeRecordId Record ID cannot be modified IDs are immutable
UnableToAquireLock Could not acquire database lock Retry operation; check for deadlocks
NoMessage Error occurred without message Check logs for additional details
CannotRemoveConfiguration Configuration cannot be removed Check dependencies

Holiday-Specific Errors

Holiday management and subscription issues.

Code Description Resolution
ExceedingMaximumHolidayDayLimit Too many holiday days configured Remove unused holidays
ExceedingMaximumHolidayTypesLimit Too many holiday types Consolidate holiday types
AlreadyUsingHoliday2 Holiday2 already in use Use different holiday slot
ExceedingMaximumHolidayForDaysValue Holiday duration too long Shorten holiday span
MasterHolidayOptInNotSet Master holiday opt-in required Enable master holiday subscription
HolidayDayAlreadySubscribed Already subscribed to this holiday No action needed
NotMasterHoliday Operation requires master holiday Use master holiday
CannotEditSubscribedHolidayDay Subscribed holidays are read-only Edit master holiday instead
CannotSubscribeMasterHolidayDayToItself Cannot self-subscribe Select different holiday

Miscellaneous Errors

Other specialized error conditions.

Code Description Resolution
CannotInsertDuplicateMoniker Moniker already exists Use unique moniker
DuplicateOrigoConfiguration Origo config already exists Update existing or use unique name

See Also