Troubleshooting

Preview Feature: CLI AI Automation is a preview feature. If you encounter any issues, please report them at support.skipper18.com.

This page covers common issues you may encounter when using the Skipper CLI, how to interpret error codes, and techniques for diagnosing problems.

Error Codes Reference

Every error returned by the CLI includes a machine-readable code field in the JSON envelope. The table below lists all possible error codes, their associated exit codes, and recommended resolutions.

CodeExit CodeMeaningResolution
UNKNOWN_VERB2The specified CLI verb does not exist.Run -cli-help to see the list of available verbs.
MULTIPLE_VERBS2More than one CLI verb was specified.Use only one -cli-* flag per invocation.
MISSING_REQUIRED2A required argument is missing.Check the verb signature in -cli-help and supply all required arguments.
INVALID_ARG_VALUE2An argument has an invalid value.Review the argument constraints in the CLI Reference.
MALFORMED_INPUT_FILE2The input file (e.g., ops.json) has invalid syntax.Validate JSON syntax with jq . ops.json and fix any parse errors.
PROJECT_LOAD_FAILED1The project file could not be loaded.Verify the file path is correct, the file exists, and it is a valid .skipper project.
IO_ERROR1A file system read/write operation failed.Check file permissions, disk space, and that output paths are writable.
EXPORT_FAILED1Code generation or export encountered an error.Check the export path, framework configuration, and project validity. Run -cli-validate first.
VALIDATION_FAILED1The project contains validation errors.Review the data field for details on each validation issue and fix them in the project.
UNKNOWN_FRAMEWORK1The specified ORM framework is not recognized.Check available frameworks in your Skipper configuration. Common values: Doctrine2, Laravel, Symfony.
MIGRATIONS_DISABLED1Migration operations are not enabled for this project.Enable migrations in the project settings before using migration-related verbs.
MIGRATIONS_OUT_OF_SYNC1Project has changes not recorded in the migration log.Run -cli-create-migration to generate a migration for pending changes.
DB_CONNECTION_FAILED1Could not connect to the database.Verify database host, port, credentials, and that the server is running.
DB_IMPORT_FAILED1Database import encountered an error.Check database connectivity and ensure the target schema is accessible.
VIEWER_LICENSE1CLI requires a paid license; Viewer (free) is not sufficient.Upgrade to a paid Skipper license.
MAINTENANCE_EXPIRED1License maintenance has expired.Renew your maintenance subscription at skipper18.com.
INVALID_OP1An operation in the ops.json file is invalid.Review the operation type and its required fields against the schema format.
INVALID_MERGE_INPUT1Merge input is invalid. Check error.details.root_cause_code for cause.Review the merge JSON structure and referenced entities.
OBJECT_NOT_FOUND1The referenced entity, field, or association was not found.Check the object name, including namespace prefix. Use -cli-schema-summary to list available objects.
NOT_IMPLEMENTED1The requested operation is not yet implemented.This feature is planned for a future release. Check the CLI Reference for currently supported verbs.
INTERNAL_ERROR3An unexpected internal error occurred.Re-run with -verbose and report the issue to support.

Validation Codes

When running -cli-validate, the response may include validation issues with their own codes. Warnings (exit 0) do not fail the command; errors (exit 1) cause VALIDATION_FAILED.

CodeExit CodeSeverityMeaning
NULLABLE_PK0warningPrimary key field is nullable -- PK should be NOT NULL.
MISSING_PK0warningEntity has no primary key field.
EMPTY_ENTITY0warningEntity has no fields defined.
MISSING_FIELD_TYPE1errorField has no data type set.
BROKEN_ASSOCIATION1errorAssociation references a missing entity or field.
INVALID_ENUM_VALUE1errorORM attribute has an invalid enum value.
INVALID_FIELD_TYPE1errorField data type is not recognized by the project's framework.
MIGRATIONS_OUT_OF_SYNC1errorProject has changes not recorded in the migration log.

Common Issues

License not loaded

If you receive a VIEWER_LICENSE or MAINTENANCE_EXPIRED error, verify the following:

  • Your license file is present in the expected location. On Windows, Skipper stores license data in the registry and in the application data directory.

  • Your maintenance subscription is active. CLI automation requires current maintenance. Check your status at skipper18.com.

  • If running in a CI/CD environment, ensure the license has been activated on the build machine. Skipper needs to have been launched at least once with the GUI to register the license before CLI mode can use it.

Viewer License Limitations

Viewer licenses can only use read-only CLI verbs: help, validate, export, schema-summary, compare, and export-diagram. Write operations (apply-patch, apply-merge, create-project, import-project, import-database, create-migration) require a full license.

Entity not found

The OBJECT_NOT_FOUND error often occurs because of namespace prefix mismatches. Skipper stores fully qualified entity names including the namespace.

  • If your entity is App\Entity\User, you must reference it as \App\Entity\User (with leading backslash) in CLI arguments.

  • Run -cli-schema-summary to see the exact names Skipper uses internally.

  • Entity names are case-sensitive.

# Wrong - may fail with OBJECT_NOT_FOUND
Skipper.exe -cli-entity-detail project.skipper Entity\User

# Correct - use the fully qualified name
Skipper.exe -cli-entity-detail project.skipper \App\Entity\User

Entity Not Found with Short Name

If two entities share the same short name in different modules (e.g. \App\Entity\User and \Admin\Entity\User), Skipper cannot disambiguate by short name alone. Use the fully qualified name (FQN) to identify the correct entity:

# Ambiguous - two "User" entities exist
Skipper.exe -cli-entity-detail project.skipper User

# Unambiguous - use FQN
Skipper.exe -cli-entity-detail project.skipper \App\Entity\User

Attribute type not found

When working with ORM attributes, the attribute path must match your framework configuration exactly.

  • Each ORM framework defines its own set of valid attribute types and paths.

  • Check your framework configuration file (e.g., Doctrine2.skipper.cfg.xml) for the list of supported attributes.

  • Ensure your project is configured for the correct framework. Mismatched framework settings will cause attribute lookups to fail.

ORM Attribute Path Format

When setting ORM attributes via patch operations, use the plain attribute name without any prefix. The orm: prefix is auto-stripped by Skipper, so both forms are equivalent:

// Correct - plain attribute name
{ "path": "table", "value": "customers" }

// Also works - orm: prefix is auto-stripped
{ "path": "orm:table", "value": "customers" }

// Recommended: always use the plain form
{ "path": "repository-class", "value": "App\Repository\UserRepository" }

Duplicate Field Name

The add_field patch operation silently skips if a field with the same name already exists on the entity. No error is returned -- the existing field is left unchanged. If you need to modify an existing field, use update_field instead.

JSON Escape Auto-Correction

AI tools frequently produce incorrectly escaped namespace strings. For example, an AI might write \App\Test (with single backslashes) instead of \\App\\Test (properly escaped). Skipper auto-corrects invalid escape sequences in namespace and class-name values:

  • \App\Test is auto-corrected to \\App\\Test (invalid escape sequences are treated as literal backslashes).

  • /App/Test (forward slashes) is also auto-converted to \\App\\Test.

  • This auto-correction applies to entity names, namespace values, and class references in patch and merge operations.

While auto-correction handles common cases, it is still recommended to use properly escaped strings in your JSON input for clarity.

Cannot delete file skipper.db

Skipper uses a SQLite database (skipper.db) for internal state. If the CLI reports that it cannot delete or access this file:

  • Another Skipper instance is running. Close any open Skipper GUI windows or other CLI processes that may be using the same project.

  • On Windows, use Task Manager to check for lingering Skipper.exe processes.

  • If the file is locked by a crashed process, you can safely delete skipper.db manually. Skipper will recreate it on the next run.

MALFORMED_INPUT_FILE

This error indicates that the input JSON file (typically ops.json) has a syntax error and cannot be parsed.

  • Validate the file with a JSON linter before passing it to Skipper:

# Validate JSON syntax
jq . ops.json

# Common issues:
# - Trailing commas after the last element in arrays/objects
# - Unescaped backslashes in strings (use \\ for literal backslash)
# - Single quotes instead of double quotes
# - Missing closing brackets

If the file was generated by an AI assistant, ask it to output raw JSON without markdown formatting (no ```json wrappers).

Debugging

When a CLI command fails or produces unexpected results, use these techniques to diagnose the issue:

Verbose output

Add the -verbose flag to any CLI command to get detailed diagnostic output on stderr. This includes project loading steps, framework resolution, entity lookups, and timing information.

Skipper.exe -cli-validate project.skipper -verbose

Reading stderr

The JSON envelope goes to stdout, while diagnostic messages go to stderr. To capture both separately:

# Capture JSON to file, see diagnostics in terminal
Skipper.exe -cli-validate project.skipper > result.json

# Capture both separately
Skipper.exe -cli-validate project.skipper > result.json 2> diagnostics.log

# View diagnostics after the run
cat diagnostics.log

Persistent log file

For CI/CD pipelines or automated runs where stderr may not be captured, use -log-file to write all diagnostic output to a persistent file:

Skipper.exe -cli-export project.skipper -log-file /var/log/skipper-cli.log

Envelope Error Structure

When a CLI verb fails, the JSON envelope contains an error object with structured information. Here is how to parse it programmatically:

{
  "status": "error",
  "command": "entity-detail",
  "error": {
    "code": "OBJECT_NOT_FOUND",
    "message": "Entity '\\User' not found in project.",
    "hint": "Use the fully qualified name including namespace, e.g. '\\App\\Entity\\User'. Run -cli-schema-summary to list all entities."
  },
  "warnings": [
    "Project contains 3 unresolved association targets."
  ],
  "meta": {
    "duration_ms": 890,
    "skipper_version": "3.3.8.1844",
    "schema_version": "3",
    "started_at": "2026-04-30T10:20:45Z"
  }
}

To handle errors in a script, check the status field first, then read the error.code for programmatic branching:

# Parse the result with jq
RESULT=$(Skipper.exe -cli-validate project.skipper 2>/dev/null)
STATUS=$(echo "$RESULT" | jq -r '.status')

if [ "$STATUS" = "error" ]; then
  CODE=$(echo "$RESULT" | jq -r '.error.code')
  MESSAGE=$(echo "$RESULT" | jq -r '.error.message')
  HINT=$(echo "$RESULT" | jq -r '.error.hint // empty')

  echo "Error [$CODE]: $MESSAGE"
  [ -n "$HINT" ] && echo "Hint: $HINT"
  exit 1
fi

echo "Validation passed."
echo "$RESULT" | jq '.data'

Key points for error handling:

  • status is always present and is either "ok" or "error".

  • error.code is a stable, machine-readable identifier. Use it for programmatic decisions (retries, fallbacks, reporting).

  • error.message is a human-readable description of what went wrong.

  • error.hint is optional and provides actionable guidance when available.

  • warnings may be present even on success. Always check warnings for potential issues that did not block execution.

For the complete list of CLI verbs and their parameters, see the CLI Reference. For general setup information, see the Introduction.