Skip to content

USL Error Code Reference

This reference documents all USL compiler error codes, organized by category. Each error includes:

  • Error code and message
  • Explanation of what causes the error
  • Example that triggers the error
  • How to fix it
  • Related errors

Quick Navigation


Syntax Errors

USL-SYN-001: Unexpected Character

Error Message: Unexpected character '{character}'

Cause: The lexer encountered a character that is not valid in USL syntax.

Example:

domain MyApp {
  entity User {
    name: String
    age: Int @ # Invalid character
  }
}

Fix: Remove or replace the invalid character. Check for: - Special characters outside of strings - Unicode characters that aren't supported - Copy-paste errors from other documents

Related Errors: USL-SYN-002


USL-SYN-002: Unterminated String Literal

Error Message: Unterminated string literal

Cause: A string was opened with a quote but never closed.

Example:

domain MyApp {
  entity User {
    name: String = "John Doe
    // Missing closing quote
  }
}

Fix: Add the closing quote:

name: String = "John Doe"

Common Mistakes: - Forgetting closing quote at end of line - Using single quotes instead of double quotes - Multiline strings without proper escaping


USL-SYN-010: Expected Token

Error Message: Expected {expected}, found {found}

Cause: The parser expected a specific token but found something else.

Example:

domain MyApp {
  entity User {
    name String  // Missing colon
  }
}

Fix: Add the missing token:

name: String

Common Cases: - Missing colons after field names - Missing braces around blocks - Missing commas in lists - Typos in keywords

Suggestion: The error message includes a helpful suggestion for what to check.


Reference Errors

USL-REF-001: Undefined Entity

Error Message: Undefined entity '{name}'

Cause: Referenced an entity that hasn't been defined.

Example:

domain MyApp {
  entity Post {
    authorId: UserId  // User entity not defined
  }
}

Fix: Define the entity before using it:

domain MyApp {
  entity User {
    id: UserId @primary
  }

  entity Post {
    authorId: UserId  // Now valid
  }
}

Common Mistakes: - Typo in entity name - Entity defined in different file/module - Order of declarations matters


USL-REF-002: Undefined Policy

Error Message: Undefined policy '{name}'

Cause: Referenced a policy that hasn't been defined.

Example:

service UserService {
  action createUser() -> User
    enforces UserPolicy.can_create  // UserPolicy not defined
}

Fix: Define the policy first:

policy UserPolicy {
  actor user: User
  rule can_create { true }
}

service UserService {
  action createUser() -> User
    enforces UserPolicy.can_create  // Now valid
}


USL-REF-003: Circular Dependency

Error Message: Circular dependency detected: {cycle}

Cause: Entities or types reference each other in a circular way.

Example:

domain MyApp {
  entity User {
    bestFriend: User  // Self-reference
  }

  entity Post {
    author: User
  }

  entity Comment {
    post: Post
  }
}

Fix: Use IDs instead of direct references:

entity User {
  id: UserId @primary
  bestFriendId: Option[UserId]  // Use ID, not entity
}

Or use forward declarations for mutual recursion.


Semantic Errors

USL-SEM-001: Type Mismatch

Error Message: Type mismatch - expected {expected}, found {found}

Cause: A value of one type was used where another type was expected.

Example:

domain MyApp {
  entity User {
    age: Int
  }

  service UserService {
    action setAge(age: String) -> User  // age is String
      implementation {
        let user = User { age: age }  // Error: expected Int, found String
      }
  }
}

Fix: Convert the value to the correct type:

action setAge(age: String) -> User
  implementation {
    let user = User { age: parseInt(age) }  // Convert to Int
  }

Common Cases: - String vs Int confusion - Option[T] vs T - Custom types (UserId vs String)


Security Errors

USL-SEC-002: Secret in Return Type

Error Message: Secret type in return value

Cause: A function returns a type marked as @secret, which could leak sensitive data.

Example:

domain MyApp {
  entity User {
    id: UserId @primary
    password: String @secret
  }

  service UserService {
    action getUser(id: UserId) -> User  // Error: returns secret
  }
}

Fix: Use a view type that excludes secrets:

view UserPublic from User {
  id: UserId
  name: String
  // password excluded
}

service UserService {
  action getUser(id: UserId) -> UserPublic  // Safe
}

Related Errors: USL-SEC-003


USL-SEC-003: Secret Leak

Error Message: Secret leaked to {destination}

Cause: Secret data is being sent to an unauthorized destination.

Example:

escape LogEvent {
  function log(user: User) -> Void  // User contains @secret fields
}

Fix: Hash, encrypt, or exclude secret fields:

escape LogEvent {
  function log(userId: UserId, action: String) -> Void  // Only log ID
}

Secure Patterns: - Hash passwords before storage - Tokenize credit cards - Use views to exclude secrets - Encrypt before logging


Policy Errors

USL-POL-001: Incomplete Policy Coverage

Error Message: Policy '{policy}' does not cover action '{action}'

Cause: A service action has no corresponding policy rule.

Example:

policy UserPolicy {
  actor user: User
  rule can_create { true }
  // Missing rule for can_delete
}

service UserService {
  action createUser() -> User
    enforces UserPolicy.can_create  // OK

  action deleteUser(id: UserId) -> Void
    enforces UserPolicy.can_delete  // Error: rule doesn't exist
}

Fix: Add the missing rule:

policy UserPolicy {
  actor user: User
  rule can_create { true }
  rule can_delete(user: User) {
    user.role == Role.Admin
  }
}


USL-POL-002: Contradictory Policy Rules

Error Message: Contradictory policy rules for action '{action}'

Cause: Two rules for the same action can return different results with the same inputs.

Example:

policy UserPolicy {
  actor user: User

  rule can_edit(target: User) {
    user.id == target.id  // Returns true for self
  }

  rule can_edit(target: User) {
    user.role == Role.Admin  // Different condition, same name
  }
}

Fix: Combine rules with logical OR:

rule can_edit(target: User) {
  user.id == target.id || user.role == Role.Admin
}


USL-POL-007: Unreachable Policy Rule

Error Message: Policy '{policy}' has unreachable rule '{rule}'

Cause: A rule can never be evaluated because earlier rules always match.

Example:

policy UserPolicy {
  actor user: User

  rule can_view { true }  // Always matches

  rule can_view(user: User) {  // Never reached
    user.role == Role.Admin
  }
}

Fix: Reorder rules or combine them:

rule can_view(target: User) {
  user.role == Role.Admin || user.id == target.id
}


USL-POL-008: Policy Not Total

Error Message: Policy '{policy}' does not cover actions: {missing_actions}

Cause: The policy doesn't have rules for all service actions.

Example:

policy UserPolicy {
  actor user: User
  rule can_create { true }
  // Missing: can_update, can_delete
}

service UserService {
  action createUser() -> User
    enforces UserPolicy.can_create

  action updateUser(id: UserId) -> User
    enforces UserPolicy.can_update  // Missing!

  action deleteUser(id: UserId) -> Void
    enforces UserPolicy.can_delete  // Missing!
}

Fix: Add rules for all actions:

policy UserPolicy {
  actor user: User
  rule can_create { true }
  rule can_update(target: User) { user.id == target.id }
  rule can_delete(target: User) { user.role == Role.Admin }
}


USL-POL-009: Contradictory Rules

Error Message: Policy '{policy}' has contradictory rules for action '{action}'

Cause: Rules with identical conditions have different effects.

Example:

policy UserPolicy {
  actor user: User

  allow rule edit_own {
    user.id == target.id
  }

  deny rule edit_own {
    user.id == target.id  // Same condition!
  }
}

Fix: Remove or modify one of the rules to have different conditions.


Layer Errors

USL-LAYER-001: Layer Violation

Error Message: {layer} layer contains forbidden construct: {construct}

Cause: Used a construct in the wrong architectural layer.

Example:

domain MyApp {
  entity User {
    id: UserId @primary

    // Domain layer can't contain HTTP code
    function sendEmail() -> Void {
      http.post("api.sendgrid.com", ...)  // Layer violation!
    }
  }
}

Fix: Move external calls to escape layer:

escape SendEmail {
  function send(to: Email) -> Result[Void, Error]
}

domain MyApp {
  entity User {
    id: UserId @primary
    email: Email
  }
}

Layer Rules: - Domain: Pure business logic only - Policy: Authorization decisions only - Behavior: State transitions only - Service: API definitions only - Escape: External integrations only


Proof Errors

USL-PROOF-001: Invariant Violation

Error Message: Transition '{transition}' violates invariant '{invariant}' of entity '{entity}'

Cause: A state transition could violate an entity invariant.

Example:

domain MyApp {
  entity Order {
    id: OrderId @primary
    total: Money
    status: OrderStatus

    invariant paid_orders_positive {
      this.status == OrderStatus.Paid -> this.total.amount > 0.0
    }
  }
}

behavior OrderLifecycle for Order {
  state Pending {
    on pay -> Paid
      effects {
        this.status = OrderStatus.Paid
        // ERROR: total might be 0!
      }
  }
}

Fix: Add a guard to ensure the invariant holds:

state Pending {
  on pay -> Paid
    requires this.total.amount > 0.0  // Enforce invariant
    effects {
      this.status = OrderStatus.Paid
    }
}


USL-PROOF-002: Initial State Invalid

Error Message: Initial state of entity '{entity}' violates invariant '{invariant}'

Cause: The initial state doesn't satisfy invariants.

Example:

entity User {
  id: UserId @primary
  email: Email
  verified: Boolean

  invariant verified_has_email {
    this.verified -> len(this.email.address) > 0
  }
}

behavior UserLifecycle for User {
  initial state Unverified {
    // If verified=true initially, invariant violated!
  }
}

Fix: Ensure initial state satisfies invariants:

behavior UserLifecycle for User {
  initial state Unverified

  // Initial effect
  on_init {
    this.verified = false  // Explicit initial value
  }
}


USL-PROOF-003: Contradictory Invariants

Error Message: Entity '{entity}' has contradictory invariants: {invariants}'

Cause: Two or more invariants cannot be satisfied simultaneously.

Example:

entity Product {
  price: Money

  invariant price_positive {
    this.price.amount > 0.0
  }

  invariant price_zero {
    this.price.amount == 0.0  // Contradicts price_positive!
  }
}

Fix: Remove or correct one of the invariants:

entity Product {
  price: Money
  isFree: Boolean

  invariant price_positive_unless_free {
    !this.isFree -> this.price.amount > 0.0
  }
}


Escape Errors

USL-ESC-001: Unapproved Capability

Error Message: Escape '{name}' requests unapproved capability '{capability}'

Cause: An escape hatch requests a capability not approved by policy.

Example:

escape SendEmail {
  capability Email.Send  // Requires approval

  function send(to: Email) -> Result[Void, Error]
}

policy EmailPolicy {
  // No rule approving Email.Send capability
}

Fix: Add policy approval:

policy EmailPolicy {
  actor user: User

  rule approve_email_send {
    user.role == Role.Admin || user.emailVerified
  }

  capability Email.Send requires approve_email_send
}


USL-ESC-900: Escape Not Declared

Error Message: Escape '{name}' not declared in escape layer

Cause: Referenced an escape that hasn't been defined.

Example:

service UserService {
  action notifyUser(userId: UserId) -> Void
    implementation {
      SendEmail.send(...)  // SendEmail not declared
    }
}

Fix: Declare the escape:

escape SendEmail {
  capability Email.Send
  function send(to: Email, body: String) -> Result[Void, Error]
}


USL-ESC-901: Capability Denied

Error Message: Escape '{name}' uses capability '{capability}' denied by policy '{policy}'

Cause: Policy explicitly denies the capability.

Example:

escape DatabaseQuery {
  capability Database.RawSQL
}

policy DatabasePolicy {
  deny rule no_raw_sql {
    // Explicitly deny raw SQL
    true
  }

  capability Database.RawSQL requires no_raw_sql
}

Fix: Either: 1. Remove the deny rule 2. Use a different capability 3. Add an exception for specific cases


USL-ESC-902: Adapter Missing

Error Message: Escape '{name}' missing required adapter for target '{target}'

Cause: No adapter implementation for the code generation target.

Example:

escape SendEmail {
  adapter typescript {
    implementation "sendgrid"
  }
  // Missing rust adapter
}

When generating Rust code:

usl generate --target rust
# Error: SendEmail missing rust adapter

Fix: Add adapter for each target:

escape SendEmail {
  adapter typescript {
    implementation "sendgrid"
  }

  adapter rust {
    implementation "reqwest + sendgrid"
    crate "sendgrid-rs"
  }
}


USL-ESC-903: Sandbox Violation

Error Message: Escape '{name}' violates sandbox constraint: {constraint}'

Cause: Escape attempts restricted operation in sandboxed environment.

Example:

escape FileSystem {
  function writeFile(path: String) -> Result[Void, Error]

  // Attempts to write outside allowed directories
}

Fix: Respect sandbox boundaries:

escape FileSystem {
  function writeFile(path: String) -> Result[Void, Error]
    sandbox {
      allowedPaths: ["/tmp", "/var/app/data"]
      maxFileSize: 10MB
    }
}


USL-ESC-904: Nondeterminism Leak

Error Message: Escape '{name}' is nondeterministic but not marked as such

Cause: Escape has unpredictable behavior but isn't declared nondeterministic.

Example:

escape RandomNumber {
  function generate() -> Int
  // Should be marked nondeterministic!
}

Fix: Mark as nondeterministic:

escape RandomNumber {
  function generate() -> Int
    nondeterministic: true
}

Nondeterministic Operations: - Random number generation - Current time/date - Network calls - File system reads - External API calls


USL-ESC-905: Resource Leak

Error Message: Escape '{name}' may leak resource '{resource}'

Cause: Escape doesn't properly cleanup resources on failure.

Example:

escape DatabaseConnection {
  function query(sql: String) -> Result[Rows, Error]
  // No cleanup on error
}

Fix: Add cleanup logic:

escape DatabaseConnection {
  function query(sql: String) -> Result[Rows, Error]
    cleanup {
      onSuccess: closeConnection()
      onError: rollback() >> closeConnection()
    }
}


USL-ESC-906: Timeout Violation

Error Message: Escape '{name}' may exceed timeout constraint of {timeout_ms}ms

Cause: Operation might take longer than allowed timeout.

Example:

escape ExternalAPI {
  function fetch(url: String) -> Result[Data, Error]
    timeout: 100ms  // Too short for network call
}

Fix: Increase timeout or optimize:

escape ExternalAPI {
  function fetch(url: String) -> Result[Data, Error]
    timeout: 5s  // Realistic for network
    retries: 3
}


Effect Errors

USL-EFFECT-001: Effect Violation

Error Message: {message}

Cause: Operation performs effect not declared in action signature.

Example:

service UserService {
  action getUser(id: UserId) -> User
    effects { Read(User) }  // Only declares Read
    implementation {
      let user = load(User, id)
      user.lastAccessedAt = now()
      store(user)  // ERROR: Write not declared!
      return user
    }
}

Fix: Declare all effects:

action getUser(id: UserId) -> User
  effects { Read(User), Write(User) }


USL-EFFECT-002: Field Not Found

Error Message: Field '{field}' not found on entity '{entity}'

Cause: Accessed non-existent field.

Example:

entity User {
  id: UserId @primary
  name: String
}

service UserService {
  action updateAge(id: UserId, age: Int) -> User
    implementation {
      let user = load(User, id)
      user.age = age  // ERROR: age field doesn't exist
      return user
    }
}

Fix: Add field to entity or use correct field name:

entity User {
  id: UserId @primary
  name: String
  age: Int  // Add missing field
}


USL-EFFECT-003: Effect Composition Error

Error Message: Effect composition violation: {message}

Cause: Effects don't compose correctly according to effect algebra rules.

Example:

service OrderService {
  action processOrder(id: OrderId) -> Order
    effects { Read(Order) }
    implementation {
      let order = load(Order, id)
      deleteOrder(id)  // Calls action with Delete effect
      // ERROR: Can't compose Read with Delete
      return order
    }
}

Fix: Declare correct effects:

action processOrder(id: OrderId) -> Order
  effects { Read(Order), Delete(Order) }

Effect Composition Rules: - Read + Read = Read - Read + Write = Write - Write + Write = Write - Write + Delete = Delete - Delete + anything = Delete


IO Errors

USL-IO-001: File Read Error

Error Message: Failed to read file: {path}

Cause: Cannot read the specified file.

Common Causes: - File doesn't exist - No read permissions - File is locked by another process - Path is a directory, not a file

Fix: 1. Verify file exists: ls -l {path} 2. Check permissions: chmod +r {path} 3. Use absolute path instead of relative 4. Close other programs using the file


USL-IO-002: File Write Error

Error Message: Failed to write file: {path}

Cause: Cannot write to the specified file.

Common Causes: - Directory doesn't exist - No write permissions - Disk is full - File is read-only

Fix: 1. Create directory: mkdir -p $(dirname {path}) 2. Check permissions: chmod +w {path} 3. Check disk space: df -h 4. Remove read-only flag


Error Resolution Workflow

When you encounter an error:

  1. Read the error message carefully
  2. Note the error code
  3. Understand what went wrong
  4. Check the span/location

  5. Look up the error in this reference

  6. Find your error code
  7. Read the explanation
  8. Review the example

  9. Apply the fix

  10. Follow the suggested solution
  11. Check for related errors
  12. Test your changes

  13. Verify the fix

    usl compile your-file.usl
    

  14. Run tests

    usl test your-file.usl
    

Getting Help

If you're still stuck after consulting this reference:

  1. Check the FAQ: Getting Started FAQ
  2. Search GitHub Issues: Issue Tracker
  3. Ask on Discord: Discord Community
  4. File a bug report: Include:
  5. Error code
  6. Full error message
  7. Minimal reproduction
  8. USL version (usl --version)

Contributing

Found an error not documented here? Please:

  1. File an issue on GitHub
  2. Include the error code and message
  3. Provide a minimal example
  4. Suggest documentation improvements

We're continuously improving error messages and documentation!