Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Error Codes

Every failure surfaced by Aperture is an APERTURE_* coded error. Each code carries a canonical message and, where operator action is meaningful, one or more fixup hints. This page is generated from the error Registry in errors/codes.go.

CodeMessageFixups
APERTURE_ACTION_UNDECLAREDaction is not declared on the object typeAdd the action verb to the object type's declared action set, or grant a verb the type already declares.
List the object type's actions to see the validated verb set.
APERTURE_ATTRIBUTE_PROVIDER_FETCHattribute provider returned an errorInspect the wrapped cause for the underlying provider failure.
Return APERTURE_NOT_FOUND from the provider for a key it does not know, so an unknown subject stays distinguishable from an unreachable directory.
APERTURE_ATTRIBUTE_PROVIDER_INVALIDattribute provider registration or attribute key is invalidRegister a non-nil provider, and at most one per slot; a duplicate is refused rather than replaced so one directory cannot silently shadow another.
Declare each attribute key at most once within a provider.
Fetch with a real key: a principal id for the user and machine slots, an account id for the account slot. An empty key names nobody.
Resolve the account wildcard "*" to a concrete account before fetching attributes; it is never a legal attribute key.
APERTURE_ATTRIBUTE_PROVIDER_UNREGISTEREDno attribute provider is registered for the slotRegister an AttributeProvider for the slot before fetching its attributes.
Check that the principal's kind maps to the slot you wired: a machine principal reads the machine slot, not the user slot.
Deployment genuinely has no subjects of this kind? Then nothing should be fetching that slot — fix the caller rather than registering an empty provider.
Seeing this from a decision? You should not: a Check/Enumerate/Explain against an unwired slot evaluates the floor bag and decides. This code reaches you only from a DIRECT attribute read (Fetch or Enumerate on the registry), so the caller to fix is that reader, not the decision path.
APERTURE_ATTRIBUTE_SLOT_UNKNOWNnot an attribute slotUse one of the three declared slots: user, machine, or account (provider.AttributeSlotUser / AttributeSlotMachine / AttributeSlotAccount).
Converting a principal kind that arrived as a bare string? Cross over with provider.ParseAttributeSlot so an unknown kind fails at the conversion instead of resolving to an empty attribute bag.
The slot set is closed on purpose — it names the parties a decision has. Model a further distinction as a FIELD in the bag, not as a fourth slot.
APERTURE_AUTHZ_DENIEDthe actor lacks the admin authority tier required for this mutationSchema mutations (permission types, roles, object-types, providers, templates, rules) require system-admin authority: an allow grant on the admin action whose object covers system:.
Grant and delegation mutations require account-admin authority in the TARGET account: an allow grant on the admin action whose object covers account:<acct>/admin:
.
Account-admin authority is confined to its own account; obtain authority in the account the mutation targets, or hold a broader (e.g. **) grant.
APERTURE_BOOTaperture failed to startCheck the APERTURE_* environment variables and any --config file.
Confirm the storage backend (memory or sqlite) is reachable.
APERTURE_CONFIG_INVALIDconfiguration is invalidValidate the YAML config and APERTURE_* env vars against the docs.
Enumerating an attribute slot that was declared without get_all: that slot is fetch-only by design, so add a get_all statement selecting a bare id, or read the slot through a fetch alone.
APERTURE_DELEGATION_DENIEDthe delegator may not bestow this grantBestow only grants that are a subset of your own effective allow grants in the account (same action and scope strategy, an equal-or-more-specific object pattern).
Confirm you hold a 'may delegate' right whose object pattern covers the grant's object.
Bestow grants only within an account you are a member of; cross-account bestowal is rejected.
APERTURE_DELEGATION_NOT_DELEGATABLEthe permission is not flagged delegatableSet Delegatable on the permission definition to allow it to be bestowed.
APERTURE_ENTITY_UNMANAGEDthis deployment does not manage the entity kind the write targetedSet the switch for the kind named in the message — APERTURE_MANAGE_ACCOUNTS, APERTURE_MANAGE_PRINCIPALS, or APERTURE_MANAGE_MEMBERSHIPS — to true (the default), then RESTART aperture: the switches are read once at startup and never re-read.
The three switches are independent; turning one on does not affect the others, so enable only the kind you meant to hand back to Aperture.
Leaving a kind unmanaged is usually deliberate — those records are mastered by an upstream system. Make the change there and let it flow in, rather than flipping the switch.
This is not a permission problem: no grant, role, or admin tier lifts it, and it refuses a system-admin exactly as it refuses anyone else.
APERTURE_IDENTITY_INVALIDobject identity is malformedUse type:id segments joined by '/', e.g. account:acme/project:atlas/document:42.
Ensure no segment is empty and every segment carries a ':' with a non-empty type and id.
Remove illegal characters; types and ids allow letters, digits, and -._~@+ only ('*' marks a wildcard in patterns).
APERTURE_IMPERSONATION_DENIEDthe operator may not impersonate this targetImpersonate only within an account both the operator and the target are members of; cross-account impersonation is refused.
Confirm the operator holds an impersonation right (augment or become) whose object pattern covers the target's identity.
Become mode requires the stronger become right; an augment right alone cannot become a target.
APERTURE_IMPERSONATION_EXPIREDthe impersonation session has expiredStart a fresh impersonation session; sessions are time-boxed and expire automatically.
APERTURE_INVALID_INPUTinput failed validationRe-check the request shape against the command or API contract.
APERTURE_INVALID_TOKENthe presented bearer credential failed verificationConfirm the token is a well-formed JWT signed by the configured issuer's keys.
Check the token issuer and audience match APERTURE_OIDC_ISSUER and APERTURE_OIDC_AUDIENCE, and that it has not expired.
For a parsec adapter, confirm the token was minted by the broker sharing the configured keyring/secret.
APERTURE_METADATA_INVALIDobject metadata violates the metadata value modelMake each field a scalar, a []any of scalars, or a map[string]any whose values are scalars, scalar arrays, or one further object level.
Replace an array of objects with a scalar array (e.g. a list of ids) — arrays of objects are rejected at any position.
Flatten a value that nests past the depth cap, or raise provider.ValueLimits.MaxDepth for the loader.
Shorten a value over the per-value size cap, or raise provider.ValueLimits.MaxBytes for the loader.
APERTURE_NOT_FOUNDthe referenced entity was not foundConfirm the identifier exists in the current account scope.
APERTURE_PROVIDER_FETCHobject provider returned an errorInspect the wrapped cause for the underlying provider failure.
Return APERTURE_NOT_FOUND from the provider for an object that does not exist.
APERTURE_PROVIDER_INVALIDobject provider registration is invalidRegister a non-nil provider under a non-empty object-type key.
Register each object type at most once; check for a duplicate registration.
APERTURE_PROVIDER_REFERENCE_INVALIDa declared object reference is not usableRegister a provider for the target object-type: a references: entry may only point at a type this registry serves.
Declare each field at most once per object-type; several fields may point at the same target, but one field has one target.
Declare the reference on the HOLDING side — the type whose provider actually returns the field — because that is the only side with a value to resolve.
Resolving a field means declaring it first: reg.DeclareReference("dataset", "current_brands", "brand"), or a references: entry in the provider's seed block.
APERTURE_PROVIDER_REFERENCE_MISMATCHa reference field's value does not identify an object of its declared target typeStore FULL canonical identities in a reference field ('brand:1', 'account:acme/brand:1'), not bare primary keys — compose them where the data is loaded, e.g. SELECT 'brand:' || b.id.
Make the field a string or a list of strings; a number, a map, or a list holding anything but strings cannot be an identity.
Check the declared target against the values the field actually carries: an identity whose terminal segment type is not the declared type is rejected rather than skipped.
APERTURE_PROVIDER_UNREGISTEREDno object provider is registered for the object typeRegister an ObjectProvider for the object type before fetching its metadata.
Confirm the object identity's terminal segment type matches a registered provider key.
Filtering an enumeration by metadata fields? Build the engine with engine.WithMetadata(registry) — the same provider registry the scope lister uses — or drop the field predicates.
APERTURE_RULE_EVALrule evaluation failedInspect the wrapped cause for the underlying evaluation failure.
Ensure the rule expression yields a boolean for the supplied context.
APERTURE_RULE_INVALIDrule AST is malformedGive each logical node the right child count: and/or take two or more, not takes exactly one.
Give every comparison a left and right operand, and every literal a scalar value.
Write variable references as dotted identifier paths, e.g. object.classification.
APERTURE_RULE_NOT_FOUNDthe referenced rule was not foundConfirm the rule reference exists in the configured rule source.
APERTURE_RULE_TYPE_ERRORrule failed expression type checkingCompare compatible types and make the rule evaluate to a boolean.
Call only functions registered with the rules engine.
APERTURE_RULE_UNKNOWN_VARIABLErule references an unknown variableReference variables under a known context root: object, principal, account, or action.
Check for a typo in the variable's root segment.
APERTURE_SCOPE_INVALIDscope strategy reference is malformedUse 'strategy' or 'strategy;param=value' form, e.g. inclusive;ids=account:acme/document:42.
Give an inclusive/exclusive strategy an 'ids' list or a 'rule' reference; implicit takes no configuration.
APERTURE_SCOPE_LISTER_UNCONFIGUREDscope enumeration requires an object lister that is not configurednot applicable
APERTURE_SCOPE_RULE_UNCONFIGUREDscope rule path requires a rule evaluator that is not configurednot applicable
APERTURE_SCOPE_UNKNOWN_STRATEGYscope strategy is not registeredUse a built-in strategy (literal, implicit, inclusive, exclusive) or register the custom key with the scope registry.
APERTURE_SQL_PROVIDER_AMBIGUOUSSQL provider's fetch statement returned more than one row for one keyFilter the fetch statement on a unique or primary key so one identity — or one subject id — selects at most one row.
A join that fans out is the usual cause; aggregate or de-duplicate the fanned-out side instead of adding LIMIT 1, which would make the metadata depend on an unspecified row order.
APERTURE_SQL_PROVIDER_CONNECTIONa declared database connection could not be resolved into a live poolSet the environment variable named by the connection's dsn_env: to a non-empty DSN before starting the process.
Check that every kind: sql provider entry's connection: matches a name declared in the top-level connections: block.
Give pool settings valid values: conn_max_lifetime and query_timeout are Go durations ("30m", "5s"), and query_timeout must be positive — there is no 'no timeout' setting.
Verify the DSN's host, port, database, and credentials by connecting with psql; the driver's message is redacted here because a DSN parse failure commonly echoes the password.
APERTURE_SQL_PROVIDER_DSN_LITERALa declarative database connection carries a literal dsn instead of dsn_envReplace the connection's dsn: key with dsn_env: naming the environment variable that holds the DSN.
Export the DSN in the process environment (or a .env file the deployment loads) rather than writing it into the seed file.
Rotate the credential if a literal DSN was ever committed — the seed file is a version-controlled artifact.
APERTURE_SQL_PROVIDER_QUERYSQL provider could not run its statementInspect the wrapped driver error for the underlying database failure.
Check the statement's placeholder count: a fetch statement binds exactly one parameter — the identity's terminal segment value for an object provider, the bare subject id for an attribute provider.
Use the placeholder syntax your engine speaks — Aperture passes placeholders through untouched and never rewrites $1 to ?.
Confirm the database is reachable and the connection's role can read the table; raise Config.Timeout if the statement is legitimately slow.
APERTURE_SQL_PROVIDER_ROW_IDENTITYSQL provider could not turn a row's id column into a usable keyObject provider: compose the full identity in the get-all statement's id column — SELECT 'brand:' || b.id AS id — because a bare primary key is not an identity and Aperture supplies no template.
Attribute provider: select the BARE subject id — SELECT u.id AS id — and never 'user:' || u.id, which is a legal opaque key that no principal id will ever match, so the slot enumerates and then answers nothing.
Name the key column id, or set the provider's id column to the alias the statement actually uses.
Make the id column textual and never NULL: cast a numeric or uuid key with ::text before concatenating it.
Check that the identity's terminal segment type is the object-type this provider is registered under; a 'brand:1' row served by the 'dataset' provider is rejected rather than cached.
APERTURE_SQL_PROVIDER_SCANSQL provider could not read a row into metadataGive every selected expression a name, and alias duplicates: each result column becomes a metadata field keyed by its column name.
Cast or serialise a column whose Go type the provider does not map (the driver value's type is named in the error, alongside the types that are mapped).
A []byte column is decoded as JSON, never as a string: wrap an array in to_jsonb(...), and cast a numeric, uuid, or bytea to ::text, ::float8, or encode(...) in the statement.
A list-valued field only arrives as a list when the statement casts it — SELECT to_jsonb(tags) AS tags, not SELECT tags, which yields the raw array literal as a string that silently matches nothing.
APERTURE_STORAGEthe storage backend returned an errorInspect the wrapped cause for the underlying storage failure.
APERTURE_STORAGE_CONSTRAINTthe database refused the write because it would break referential integrityDelete the rows that reference the record first: a principal's memberships and group memberships, a permission's role assignments and grants, a role's principal assignments, an object type's permissions, an account's memberships and grants, and the grants that name a principal, role, or group as their subject.
Creating a record? Create what it references first — a permission needs its object type, a membership and a group member need their principal, a grant and a role assignment need their permission, and a membership and a grant need their account.
Refused on a grant's subject? subject_kind chooses the table subject_id must exist in — principal, role, or group. A grant naming a role id under kind "group" is refused even though that id exists elsewhere.
Refused on an account id? It must name a real account, or be exactly "" (the all-accounts wildcard). "" is a sentinel, not an account: it needs no account record and cannot be given one.
Ids are immutable in Aperture: to change one, create the new record, move the children, then delete the old one — an UPDATE that moved a key is refused rather than silently re-parenting.
Seeing this from Setup rather than a write? The connection is not enforcing foreign keys. Open the store with sqlite.Open, which forces _pragma=foreign_keys(1) into the DSN whatever the caller passed.
APERTURE_STORAGE_SCHEMA_INCOMPATIBLEthe existing database was written by an incompatible build and cannot be upgradedRecreate the database: move or delete the old file, start Aperture so Setup builds the schema fresh, then re-seed it.
Point the store at a new, empty database if you need to keep the old file for reference.
Do not expect an in-place upgrade: Aperture ships no migration tool and no schema versioning, so a schema break is a hard break by design.
APERTURE_TEMPLATE_INVALIDthe provisioning template is malformedGive the template a non-empty name, a version of at least 1, and at least one grant.
Declare every parameter a grant references; write references as ${name} with a declared parameter.
Give each template grant a valid subject, a permission id, an allow/deny effect, and a non-empty object pattern.
APERTURE_TEMPLATE_PARAMthe template apply supplied invalid parametersSupply a value for every parameter the template declares, and no parameters it does not.
A segment-typed parameter value must be a legal identity component: letters, digits, and -._~@+ only.
APERTURE_UNAUTHENTICATEDthe request could not be resolved to a known principalPresent a credential: send an Authorization: Bearer <token> header.
With the dev/static authenticator the bearer IS the principal id; send a non-empty value.
Confirm the verified token carries the configured principal claim (APERTURE_AUTH_PRINCIPAL_CLAIM, default 'sub').
APERTURE_UNIMPLEMENTEDthis surface is not yet implementednot applicable